msm: consistency for equally ranked keys
[platform/upstream/rpm.git] / rpmio / digest_beecrypt.c
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 }