~ubuntu-branches/debian/sid/rpm/sid

« back to all changes in this revision

Viewing changes to rpmio/digest_beecrypt.c

  • Committer: Package Import Robot
  • Author(s): Michal Čihař
  • Date: 2013-06-06 11:39:34 UTC
  • mfrom: (1.1.16)
  • Revision ID: package-import@ubuntu.com-20130606113934-ela3du14fyba0t6u
Tags: 4.11.0.1-1
* New upstream release.
* Bump standards to 3.9.4.
* Refresh patches, update patch from Fedora.
* Build with Lua 5.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "system.h"
 
2
 
 
3
#include <beecrypt.h>
 
4
#include <dsa.h>
 
5
#include <endianness.h>
 
6
#include <md5.h>
 
7
#include <mp.h>
 
8
#include <rsa.h>
 
9
#include <rsapk.h>
 
10
#include <sha1.h>
 
11
#if HAVE_BEECRYPT_API_H
 
12
#include <sha256.h>
 
13
#include <sha384.h>
 
14
#include <sha512.h>
 
15
#endif
 
16
 
 
17
#include <rpm/rpmpgp.h>
 
18
#include "rpmio/digest.h"
 
19
#include "rpmio/rpmio_internal.h"
 
20
#include "debug.h"
 
21
 
 
22
/**
 
23
 * MD5/SHA1 digest private data.
 
24
 */
 
25
struct DIGEST_CTX_s {
 
26
    rpmDigestFlags flags;       /*!< Bit(s) to control digest operation. */
 
27
    int algo;                   /*!< Used hash algorithm */
 
28
    uint32_t datalen;           /*!< No. bytes in block of plaintext data. */
 
29
    uint32_t paramlen;          /*!< No. bytes of digest parameters. */
 
30
    uint32_t digestlen;         /*!< No. bytes of digest. */
 
31
    void * param;               /*!< Digest parameters. */
 
32
    int (*Reset) (void * param);        /*!< Digest initialize. */
 
33
    int (*Update) (void * param, const byte * data, size_t size);       /*!< Digest transform. */
 
34
    int (*Digest) (void * param, byte * digest);        /*!< Digest finish. */
 
35
};
 
36
 
 
37
 
 
38
/****************************  init   ************************************/
 
39
 
 
40
int rpmInitCrypto(void) {
 
41
    return 0;
 
42
}
 
43
 
 
44
int rpmFreeCrypto(void) {
 
45
    return 0;
 
46
}
 
47
 
 
48
/****************************  digest ************************************/
 
49
 
 
50
DIGEST_CTX rpmDigestDup(DIGEST_CTX octx)
 
51
{
 
52
    DIGEST_CTX nctx = NULL;
 
53
    if (octx) {
 
54
        nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
 
55
        nctx->param = memcpy(xcalloc(1, nctx->paramlen), octx->param, nctx->paramlen);
 
56
    }
 
57
    return nctx;
 
58
}
 
59
 
 
60
size_t rpmDigestLength(int hashalgo)
 
61
{
 
62
    switch (hashalgo) {
 
63
    case PGPHASHALGO_MD5:
 
64
        return 16;
 
65
    case PGPHASHALGO_SHA1:
 
66
        return 20;
 
67
#if HAVE_BEECRYPT_API_H
 
68
    case PGPHASHALGO_SHA256:
 
69
        return 32;
 
70
    case PGPHASHALGO_SHA384:
 
71
        return 48;
 
72
    case PGPHASHALGO_SHA512:
 
73
        return 64;
 
74
#endif
 
75
    default:
 
76
        return 0;
 
77
    }
 
78
}
 
79
 
 
80
DIGEST_CTX rpmDigestInit(int hashalgo, rpmDigestFlags flags)
 
81
{
 
82
    DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
 
83
 
 
84
    ctx->flags = flags;
 
85
    ctx->algo = hashalgo;
 
86
 
 
87
    switch (hashalgo) {
 
88
    case PGPHASHALGO_MD5:
 
89
        ctx->digestlen = 16;
 
90
        ctx->datalen = 64;
 
91
        ctx->paramlen = sizeof(md5Param);
 
92
        ctx->param = xcalloc(1, ctx->paramlen);
 
93
        ctx->Reset = (void *) md5Reset;
 
94
        ctx->Update = (void *) md5Update;
 
95
        ctx->Digest = (void *) md5Digest;
 
96
        break;
 
97
    case PGPHASHALGO_SHA1:
 
98
        ctx->digestlen = 20;
 
99
        ctx->datalen = 64;
 
100
        ctx->paramlen = sizeof(sha1Param);
 
101
        ctx->param = xcalloc(1, ctx->paramlen);
 
102
        ctx->Reset = (void *) sha1Reset;
 
103
        ctx->Update = (void *) sha1Update;
 
104
        ctx->Digest = (void *) sha1Digest;
 
105
        break;
 
106
#if HAVE_BEECRYPT_API_H
 
107
    case PGPHASHALGO_SHA256:
 
108
        ctx->digestlen = 32;
 
109
        ctx->datalen = 64;
 
110
        ctx->paramlen = sizeof(sha256Param);
 
111
        ctx->param = xcalloc(1, ctx->paramlen);
 
112
        ctx->Reset = (void *) sha256Reset;
 
113
        ctx->Update = (void *) sha256Update;
 
114
        ctx->Digest = (void *) sha256Digest;
 
115
        break;
 
116
    case PGPHASHALGO_SHA384:
 
117
        ctx->digestlen = 48;
 
118
        ctx->datalen = 128;
 
119
        ctx->paramlen = sizeof(sha384Param);
 
120
        ctx->param = xcalloc(1, ctx->paramlen);
 
121
        ctx->Reset = (void *) sha384Reset;
 
122
        ctx->Update = (void *) sha384Update;
 
123
        ctx->Digest = (void *) sha384Digest;
 
124
        break;
 
125
    case PGPHASHALGO_SHA512:
 
126
        ctx->digestlen = 64;
 
127
        ctx->datalen = 128;
 
128
        ctx->paramlen = sizeof(sha512Param);
 
129
        ctx->param = xcalloc(1, ctx->paramlen);
 
130
        ctx->Reset = (void *) sha512Reset;
 
131
        ctx->Update = (void *) sha512Update;
 
132
        ctx->Digest = (void *) sha512Digest;
 
133
        break;
 
134
#endif
 
135
    case PGPHASHALGO_RIPEMD160:
 
136
    case PGPHASHALGO_MD2:
 
137
    case PGPHASHALGO_TIGER192:
 
138
    case PGPHASHALGO_HAVAL_5_160:
 
139
    default:
 
140
        free(ctx);
 
141
        return NULL;
 
142
    }
 
143
 
 
144
    (*ctx->Reset)(ctx->param);
 
145
    return ctx;
 
146
}
 
147
 
 
148
int rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
 
149
{
 
150
    if (ctx == NULL)
 
151
        return -1;
 
152
 
 
153
    return (*ctx->Update) (ctx->param, data, len);
 
154
}
 
155
 
 
156
int rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
 
157
{
 
158
    byte * digest;
 
159
    char * t;
 
160
    int i;
 
161
 
 
162
    if (ctx == NULL)
 
163
        return -1;
 
164
    digest = xmalloc(ctx->digestlen);
 
165
 
 
166
    /* FIX: check rc */
 
167
    (void) (*ctx->Digest) (ctx->param, digest);
 
168
 
 
169
    /* Return final digest. */
 
170
    if (!asAscii) {
 
171
        if (lenp) *lenp = ctx->digestlen;
 
172
        if (datap) {
 
173
            *datap = digest;
 
174
            digest = NULL;
 
175
        }
 
176
    } else {
 
177
        if (lenp) *lenp = (2*ctx->digestlen) + 1;
 
178
        if (datap) {
 
179
            const byte * s = (const byte *) digest;
 
180
            static const char hex[] = "0123456789abcdef";
 
181
 
 
182
            *datap = t = xmalloc((2*ctx->digestlen) + 1);
 
183
            for (i = 0 ; i < ctx->digestlen; i++) {
 
184
                *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
 
185
                *t++ = hex[ (unsigned)((*s++   ) & 0x0f) ];
 
186
            }
 
187
            *t = '\0';
 
188
        }
 
189
    }
 
190
    if (digest) {
 
191
        memset(digest, 0, ctx->digestlen);      /* In case it's sensitive */
 
192
        free(digest);
 
193
    }
 
194
    memset(ctx->param, 0, ctx->paramlen);       /* In case it's sensitive */
 
195
    free(ctx->param);
 
196
    memset(ctx, 0, sizeof(*ctx));       /* In case it's sensitive */
 
197
    free(ctx);
 
198
    return 0;
 
199
}
 
200
 
 
201
/**************************** helpers ************************************/
 
202
 
 
203
static inline char * pgpHexCvt(char *t, const byte *s, int nbytes)
 
204
{
 
205
    static char hex[] = "0123456789abcdef";
 
206
    while (nbytes-- > 0) { 
 
207
        unsigned int i;
 
208
        i = *s++;
 
209
        *t++ = hex[ (i >> 4) & 0xf ];
 
210
        *t++ = hex[ (i     ) & 0xf ];
 
211
    }    
 
212
    *t = '\0';
 
213
    return t;
 
214
}
 
215
 
 
216
static const char * pgpMpiHex(const byte *p, const byte *pend)
 
217
{
 
218
    static char prbuf[2048];
 
219
    char *t = prbuf;
 
220
    int nbytes =  pgpMpiLen(p) - 2;
 
221
    if (nbytes > 1024 || nbytes > pend - (p + 2))
 
222
        return NULL;
 
223
    t = pgpHexCvt(t, p+2, nbytes);
 
224
    return prbuf;
 
225
}
 
226
 
 
227
static int pgpHexSet(int lbits, mpnumber * mpn, const byte * p, const byte * pend)
 
228
{
 
229
    unsigned int mbits = pgpMpiBits(p);
 
230
    unsigned int nbits;
 
231
    unsigned int nbytes;
 
232
    char *t;
 
233
    unsigned int ix;
 
234
 
 
235
    nbits = (lbits > mbits ? lbits : mbits);
 
236
    nbytes = ((nbits + 7) >> 3);
 
237
    t = xmalloc(2*nbytes+1);
 
238
    ix = 2 * ((nbits - mbits) >> 3);
 
239
 
 
240
    if (ix > 0) memset(t, (int)'0', ix);
 
241
    strcpy(t+ix, pgpMpiHex(p, pend));
 
242
    (void) mpnsethex(mpn, t);
 
243
    t = _free(t);
 
244
    return 0;
 
245
}
 
246
 
 
247
static void pgpFreeSigRSADSA(pgpDigAlg sa)
 
248
{
 
249
    if (sa->data)
 
250
        free(sa->data);
 
251
    sa->data = 0;
 
252
}
 
253
 
 
254
static void pgpFreeKeyRSADSA(pgpDigAlg sa)
 
255
{
 
256
    if (sa->data)
 
257
        free(sa->data);
 
258
    sa->data = 0;
 
259
}
 
260
 
 
261
 
 
262
/****************************** RSA **************************************/
 
263
 
 
264
struct pgpDigSigRSA_s {
 
265
    mpnumber c;
 
266
};
 
267
 
 
268
struct pgpDigKeyRSA_s {
 
269
    rsapk rsa_pk;
 
270
};
 
271
 
 
272
static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num,
 
273
                           const uint8_t *p, const uint8_t *pend)
 
274
{
 
275
    struct pgpDigSigRSA_s *sig = pgpsig->data;
 
276
    int rc = 1;
 
277
 
 
278
    switch (num) {
 
279
    case 0:
 
280
        sig = pgpsig->data = xcalloc(1, sizeof(*sig));
 
281
        (void) mpnsethex(&sig->c, pgpMpiHex(p, pend));
 
282
        rc = 0;
 
283
        break;
 
284
    }
 
285
    return rc;
 
286
}
 
287
 
 
288
static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num,
 
289
                           const uint8_t *p, const uint8_t *pend)
 
290
{
 
291
    struct pgpDigKeyRSA_s *key = pgpkey->data;
 
292
    int rc = 1;
 
293
 
 
294
    if (!key)
 
295
        key = pgpkey->data = xcalloc(1, sizeof(*key));
 
296
    switch (num) {
 
297
    case 0:
 
298
        (void) mpbsethex(&key->rsa_pk.n, pgpMpiHex(p, pend));
 
299
        rc = 0;
 
300
        break;
 
301
    case 1:
 
302
        (void) mpnsethex(&key->rsa_pk.e, pgpMpiHex(p, pend));
 
303
        rc = 0;
 
304
        break;
 
305
    }
 
306
    return rc;
 
307
}
 
308
 
 
309
static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo)
 
310
{
 
311
    struct pgpDigKeyRSA_s *key = pgpkey->data;
 
312
    struct pgpDigSigRSA_s *sig = pgpsig->data;
 
313
    const char * prefix = NULL;
 
314
    mpnumber rsahm;
 
315
    int rc = 1;
 
316
 
 
317
    if (!sig || !key)
 
318
        return rc;
 
319
 
 
320
    switch (hash_algo) {
 
321
    case PGPHASHALGO_MD5:
 
322
        prefix = "3020300c06082a864886f70d020505000410";
 
323
        break;
 
324
    case PGPHASHALGO_SHA1:
 
325
        prefix = "3021300906052b0e03021a05000414";
 
326
        break;
 
327
    case PGPHASHALGO_MD2:
 
328
        prefix = "3020300c06082a864886f70d020205000410";
 
329
        break;
 
330
    case PGPHASHALGO_SHA256:
 
331
        prefix = "3031300d060960864801650304020105000420";
 
332
        break;
 
333
    case PGPHASHALGO_SHA384:
 
334
        prefix = "3041300d060960864801650304020205000430";
 
335
        break;
 
336
    case PGPHASHALGO_SHA512:
 
337
        prefix = "3051300d060960864801650304020305000440";
 
338
        break;
 
339
    default:
 
340
        return 1;
 
341
    }
 
342
 
 
343
    /* Generate RSA modulus parameter. */
 
344
    {   unsigned int nbits = MP_WORDS_TO_BITS(sig->c.size);
 
345
        unsigned int nb = (nbits + 7) >> 3;
 
346
        byte *buf, *bp;
 
347
 
 
348
        if (nb < 3)
 
349
            return 1;
 
350
        buf = xmalloc(nb);
 
351
        memset(buf, 0xff, nb);
 
352
        buf[0] = 0x00;
 
353
        buf[1] = 0x01;
 
354
        bp = buf + nb - strlen(prefix)/2 - hashlen - 1;
 
355
        if (bp < buf)
 
356
            return 1;
 
357
        *bp++ = 0;
 
358
        for (; *prefix; prefix += 2)
 
359
            *bp++ = (rnibble(prefix[0]) << 4) | rnibble(prefix[1]);
 
360
        memcpy(bp, hash, hashlen);
 
361
        mpnzero(&rsahm);
 
362
        (void) mpnsetbin(&rsahm, buf, nb);
 
363
        buf = _free(buf);
 
364
    }
 
365
#if HAVE_BEECRYPT_API_H
 
366
    rc = rsavrfy(&key->rsa_pk.n, &key->rsa_pk.e, &sig->c, &rsahm) == 1 ? 0 : 1;
 
367
#else
 
368
    rc = rsavrfy(&key->rsa_pk, &rsahm, &sig->c) == 1 ? 0 : 1;
 
369
#endif
 
370
    mpnfree(&rsahm);
 
371
    return rc;
 
372
}
 
373
 
 
374
 
 
375
/****************************** DSA **************************************/
 
376
 
 
377
struct pgpDigSigDSA_s {
 
378
    mpnumber r;
 
379
    mpnumber s;
 
380
};
 
381
 
 
382
struct pgpDigKeyDSA_s {
 
383
    mpbarrett p;
 
384
    mpbarrett q;
 
385
    mpnumber g;
 
386
    mpnumber y;
 
387
};
 
388
 
 
389
static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num,
 
390
                           const uint8_t *p, const uint8_t *pend)
 
391
{
 
392
    struct pgpDigSigDSA_s *sig = pgpsig->data;
 
393
    int rc = 1;
 
394
 
 
395
    switch (num) {
 
396
    case 0:
 
397
        sig = pgpsig->data = xcalloc(1, sizeof(*sig));
 
398
        rc = pgpHexSet(160, &sig->r, p, pend);
 
399
        break;
 
400
    case 1:
 
401
        rc = pgpHexSet(160, &sig->s, p, pend);
 
402
        break;
 
403
    }
 
404
    return rc;
 
405
}
 
406
 
 
407
static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num,
 
408
                           const uint8_t *p, const uint8_t *pend)
 
409
{
 
410
    struct pgpDigKeyDSA_s *key = pgpkey->data;
 
411
    int rc = 1;
 
412
 
 
413
    if (!key)
 
414
        key = pgpkey->data = xcalloc(1, sizeof(*key));
 
415
 
 
416
    switch (num) {
 
417
    case 0:
 
418
        mpbsethex(&key->p, pgpMpiHex(p, pend));
 
419
        rc = 0;
 
420
        break;
 
421
    case 1:
 
422
        mpbsethex(&key->q, pgpMpiHex(p, pend));
 
423
        rc = 0;
 
424
        break;
 
425
    case 2:
 
426
        mpnsethex(&key->g, pgpMpiHex(p, pend));
 
427
        rc = 0;
 
428
        break;
 
429
    case 3:
 
430
        mpnsethex(&key->y, pgpMpiHex(p, pend));
 
431
        rc = 0;
 
432
        break;
 
433
    }
 
434
    return rc;
 
435
}
 
436
 
 
437
static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo)
 
438
{
 
439
    struct pgpDigKeyDSA_s *key = pgpkey->data;
 
440
    struct pgpDigSigDSA_s *sig = pgpsig->data;
 
441
    mpnumber hm;
 
442
    int rc = 1;
 
443
 
 
444
    if (sig && key) {
 
445
        mpnzero(&hm);
 
446
        mpnsetbin(&hm, hash, hashlen);
 
447
        rc = dsavrfy(&key->p, &key->q, &key->g, &hm, &key->y, &sig->r, &sig->s) == 1 ? 0 : 1;
 
448
        mpnfree(&hm);
 
449
    }
 
450
    return rc;
 
451
}
 
452
 
 
453
static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num,
 
454
                         const uint8_t *p, const uint8_t *pend)
 
455
{
 
456
    return 1;
 
457
}
 
458
 
 
459
static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
 
460
                         uint8_t *hash, size_t hashlen, int hash_algo)
 
461
{
 
462
    return 1;
 
463
}
 
464
 
 
465
pgpDigAlg pgpPubkeyNew(int algo)
 
466
{
 
467
    pgpDigAlg ka = xcalloc(1, sizeof(*ka));;
 
468
 
 
469
    switch (algo) {
 
470
    case PGPPUBKEYALGO_RSA:
 
471
        ka->setmpi = pgpSetKeyMpiRSA;
 
472
        ka->free = pgpFreeKeyRSADSA;
 
473
        ka->mpis = 2;
 
474
        break;
 
475
    case PGPPUBKEYALGO_DSA:
 
476
        ka->setmpi = pgpSetKeyMpiDSA;
 
477
        ka->free = pgpFreeKeyRSADSA;
 
478
        ka->mpis = 4;
 
479
        break;
 
480
    default:
 
481
        ka->setmpi = pgpSetMpiNULL;
 
482
        ka->mpis = -1;
 
483
        break;
 
484
    }
 
485
 
 
486
    ka->verify = pgpVerifyNULL; /* keys can't be verified */
 
487
 
 
488
    return ka;
 
489
}
 
490
 
 
491
pgpDigAlg pgpSignatureNew(int algo)
 
492
{
 
493
    pgpDigAlg sa = xcalloc(1, sizeof(*sa));
 
494
 
 
495
    switch (algo) {
 
496
    case PGPPUBKEYALGO_RSA:
 
497
        sa->setmpi = pgpSetSigMpiRSA;
 
498
        sa->free = pgpFreeSigRSADSA;
 
499
        sa->verify = pgpVerifySigRSA;
 
500
        sa->mpis = 1;
 
501
        break;
 
502
    case PGPPUBKEYALGO_DSA:
 
503
        sa->setmpi = pgpSetSigMpiDSA;
 
504
        sa->free = pgpFreeSigRSADSA;
 
505
        sa->verify = pgpVerifySigDSA;
 
506
        sa->mpis = 2;
 
507
        break;
 
508
    default:
 
509
        sa->setmpi = pgpSetMpiNULL;
 
510
        sa->verify = pgpVerifyNULL;
 
511
        sa->mpis = -1;
 
512
        break;
 
513
    }
 
514
    return sa;
 
515
}