1 #include "system.h"
2 
3 #include <beecrypt/beecrypt.h>
4 #include <beecrypt/dsa.h>
5 #include <beecrypt/endianness.h>
6 #include <beecrypt/md5.h>
7 #include <beecrypt/mp.h>
8 #include <beecrypt/rsa.h>
9 #include <beecrypt/rsapk.h>
10 #include <beecrypt/sha1.h>
11 #if HAVE_BEECRYPT_API_H
12 #include <beecrypt/sha256.h>
13 #include <beecrypt/sha384.h>
14 #include <beecrypt/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 
rpmInitCrypto(void)40 int rpmInitCrypto(void) {
41     return 0;
42 }
43 
rpmFreeCrypto(void)44 int rpmFreeCrypto(void) {
45     return 0;
46 }
47 
48 /****************************  digest ************************************/
49 
rpmDigestDup(DIGEST_CTX octx)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 
rpmDigestLength(int hashalgo)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 
rpmDigestInit(int hashalgo,rpmDigestFlags flags)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     default:
136 	free(ctx);
137 	return NULL;
138     }
139 
140     (*ctx->Reset)(ctx->param);
141     return ctx;
142 }
143 
rpmDigestUpdate(DIGEST_CTX ctx,const void * data,size_t len)144 int rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
145 {
146     if (ctx == NULL)
147 	return -1;
148 
149     return (*ctx->Update) (ctx->param, data, len);
150 }
151 
rpmDigestFinal(DIGEST_CTX ctx,void ** datap,size_t * lenp,int asAscii)152 int rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
153 {
154     byte * digest;
155     char * t;
156     int i;
157 
158     if (ctx == NULL)
159 	return -1;
160     digest = xmalloc(ctx->digestlen);
161 
162     /* FIX: check rc */
163     (void) (*ctx->Digest) (ctx->param, digest);
164 
165     /* Return final digest. */
166     if (!asAscii) {
167 	if (lenp) *lenp = ctx->digestlen;
168 	if (datap) {
169 	    *datap = digest;
170 	    digest = NULL;
171 	}
172     } else {
173 	if (lenp) *lenp = (2*ctx->digestlen) + 1;
174 	if (datap) {
175 	    const byte * s = (const byte *) digest;
176 	    static const char hex[] = "0123456789abcdef";
177 
178 	    *datap = t = xmalloc((2*ctx->digestlen) + 1);
179 	    for (i = 0 ; i < ctx->digestlen; i++) {
180 		*t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
181 		*t++ = hex[ (unsigned)((*s++   ) & 0x0f) ];
182 	    }
183 	    *t = '\0';
184 	}
185     }
186     if (digest) {
187 	memset(digest, 0, ctx->digestlen);	/* In case it's sensitive */
188 	free(digest);
189     }
190     memset(ctx->param, 0, ctx->paramlen);	/* In case it's sensitive */
191     free(ctx->param);
192     memset(ctx, 0, sizeof(*ctx));	/* In case it's sensitive */
193     free(ctx);
194     return 0;
195 }
196 
197 
198 /****************************** RSA **************************************/
199 
200 struct pgpDigSigRSA_s {
201     mpnumber c;
202 };
203 
204 struct pgpDigKeyRSA_s {
205     rsapk rsa_pk;
206     int nbytes;
207 };
208 
pgpSetSigMpiRSA(pgpDigAlg pgpsig,int num,const uint8_t * p)209 static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num, const uint8_t *p)
210 {
211     struct pgpDigSigRSA_s *sig = pgpsig->data;
212     int mlen = pgpMpiLen(p) - 2;
213     int rc = 1;
214 
215     if (!sig)
216 	sig = pgpsig->data = xcalloc(1, sizeof(*sig));
217 
218     switch (num) {
219     case 0:
220 	if (!mpnsetbin(&sig->c, p + 2, mlen))
221 	    rc = 0;
222 	break;
223     }
224     return rc;
225 }
226 
pgpSetKeyMpiRSA(pgpDigAlg pgpkey,int num,const uint8_t * p)227 static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
228 {
229     struct pgpDigKeyRSA_s *key = pgpkey->data;
230     int mlen = pgpMpiLen(p) - 2;
231     int rc = 1;
232 
233     if (!key)
234 	key = pgpkey->data = xcalloc(1, sizeof(*key));
235 
236     switch (num) {
237     case 0:
238 	key->nbytes = mlen;
239 	if (!mpbsetbin(&key->rsa_pk.n, p + 2, mlen))
240 	    rc = 0;
241 	break;
242     case 1:
243 	if (!mpnsetbin(&key->rsa_pk.e, p + 2, mlen))
244 	    rc = 0;
245 	break;
246     }
247     return rc;
248 }
249 
pkcs1pad(mpnumber * rsahm,int nbytes,const char * prefix,uint8_t * hash,size_t hashlen)250 static int pkcs1pad(mpnumber *rsahm, int nbytes, const char *prefix, uint8_t *hash, size_t hashlen)
251 {
252     int datalen = strlen(prefix) / 2 + hashlen;
253     byte *buf, *bp;
254     int rc = 1;
255 
256     if (nbytes < 4 + datalen)
257 	return 1;
258     buf = xmalloc(nbytes);
259     memset(buf, 0xff, nbytes);
260     buf[0] = 0x00;
261     buf[1] = 0x01;
262     bp = buf + nbytes - datalen;
263     bp[-1] = 0;
264     for (; *prefix; prefix += 2)
265 	*bp++ = (rnibble(prefix[0]) << 4) | rnibble(prefix[1]);
266     memcpy(bp, hash, hashlen);
267     if (!mpnsetbin(rsahm, buf, nbytes))
268 	rc = 0;
269     buf = _free(buf);
270     return rc;
271 }
272 
pgpVerifySigRSA(pgpDigAlg pgpkey,pgpDigAlg pgpsig,uint8_t * hash,size_t hashlen,int hash_algo)273 static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo)
274 {
275     struct pgpDigKeyRSA_s *key = pgpkey->data;
276     struct pgpDigSigRSA_s *sig = pgpsig->data;
277     const char * prefix = NULL;
278     mpnumber rsahm;
279     int rc = 1;
280 
281     if (!sig || !key)
282 	return rc;
283 
284     switch (hash_algo) {
285     case PGPHASHALGO_MD5:
286         prefix = "3020300c06082a864886f70d020505000410";
287         break;
288     case PGPHASHALGO_SHA1:
289         prefix = "3021300906052b0e03021a05000414";
290         break;
291     case PGPHASHALGO_SHA256:
292         prefix = "3031300d060960864801650304020105000420";
293         break;
294     case PGPHASHALGO_SHA384:
295         prefix = "3041300d060960864801650304020205000430";
296         break;
297     case PGPHASHALGO_SHA512:
298         prefix = "3051300d060960864801650304020305000440";
299         break;
300     default:
301 	return 1;
302     }
303 
304     memset(&rsahm, 0, sizeof(rsahm));
305     if (pkcs1pad(&rsahm, key->nbytes, prefix, hash, hashlen) != 0)
306 	return 1;
307 
308 #if HAVE_BEECRYPT_API_H
309     rc = rsavrfy(&key->rsa_pk.n, &key->rsa_pk.e, &sig->c, &rsahm) == 1 ? 0 : 1;
310 #else
311     rc = rsavrfy(&key->rsa_pk, &rsahm, &sig->c) == 1 ? 0 : 1;
312 #endif
313     mpnfree(&rsahm);
314     return rc;
315 }
316 
pgpFreeSigRSA(pgpDigAlg pgpsig)317 static void pgpFreeSigRSA(pgpDigAlg pgpsig)
318 {
319     struct pgpDigSigRSA_s *sig = pgpsig->data;
320     if (sig) {
321 	mpnfree(&sig->c);
322 	pgpsig->data = _free(sig);
323     }
324 }
325 
pgpFreeKeyRSA(pgpDigAlg pgpkey)326 static void pgpFreeKeyRSA(pgpDigAlg pgpkey)
327 {
328     struct pgpDigKeyRSA_s *key = pgpkey->data;
329     if (key) {
330 	mpbfree(&key->rsa_pk.n);
331 	mpnfree(&key->rsa_pk.e);
332 	pgpkey->data = _free(key);
333     }
334 }
335 
336 
337 /****************************** DSA **************************************/
338 
339 struct pgpDigSigDSA_s {
340     mpnumber r;
341     mpnumber s;
342 };
343 
344 struct pgpDigKeyDSA_s {
345     mpbarrett p;
346     mpbarrett q;
347     mpnumber g;
348     mpnumber y;
349     int qbytes;
350 };
351 
pgpSetSigMpiDSA(pgpDigAlg pgpsig,int num,const uint8_t * p)352 static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num, const uint8_t *p)
353 {
354     struct pgpDigSigDSA_s *sig = pgpsig->data;
355     int mlen = pgpMpiLen(p) - 2;
356     int rc = 1;
357 
358     if (!sig)
359 	sig = pgpsig->data = xcalloc(1, sizeof(*sig));
360 
361     switch (num) {
362     case 0:
363 	if (!mpnsetbin(&sig->r, p + 2, mlen))
364 	    rc = 0;
365 	break;
366     case 1:
367 	if (!mpnsetbin(&sig->s, p + 2, mlen))
368 	    rc = 0;
369 	break;
370     }
371     return rc;
372 }
373 
pgpSetKeyMpiDSA(pgpDigAlg pgpkey,int num,const uint8_t * p)374 static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
375 {
376     struct pgpDigKeyDSA_s *key = pgpkey->data;
377     int mlen = pgpMpiLen(p) - 2;
378     int rc = 1;
379 
380     if (!key)
381 	key = pgpkey->data = xcalloc(1, sizeof(*key));
382 
383     switch (num) {
384     case 0:
385 	if (!mpbsetbin(&key->p, p + 2, mlen))
386 	    rc = 0;
387 	break;
388     case 1:
389 	key->qbytes = mlen;
390 	if (!mpbsetbin(&key->q, p + 2, mlen))
391 	    rc = 0;
392 	break;
393     case 2:
394 	if (!mpnsetbin(&key->g, p + 2, mlen))
395 	    rc = 0;
396 	break;
397     case 3:
398 	if (!mpnsetbin(&key->y, p + 2, mlen))
399 	    rc = 0;
400 	break;
401     }
402     return rc;
403 }
404 
pgpVerifySigDSA(pgpDigAlg pgpkey,pgpDigAlg pgpsig,uint8_t * hash,size_t hashlen,int hash_algo)405 static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo)
406 {
407     struct pgpDigKeyDSA_s *key = pgpkey->data;
408     struct pgpDigSigDSA_s *sig = pgpsig->data;
409     mpnumber hm;
410     int rc = 1;
411 
412     if (sig && key && hashlen >= key->qbytes) {
413 	mpnzero(&hm);
414 	mpnsetbin(&hm, hash, key->qbytes);
415 	rc = dsavrfy(&key->p, &key->q, &key->g, &hm, &key->y, &sig->r, &sig->s) == 1 ? 0 : 1;
416 	mpnfree(&hm);
417     }
418     return rc;
419 }
420 
pgpFreeSigDSA(pgpDigAlg pgpsig)421 static void pgpFreeSigDSA(pgpDigAlg pgpsig)
422 {
423     struct pgpDigSigDSA_s *sig = pgpsig->data;
424     if (sig) {
425 	mpnfree(&sig->r);
426 	mpnfree(&sig->s);
427 	pgpsig->data = _free(sig);
428     }
429 }
430 
pgpFreeKeyDSA(pgpDigAlg pgpkey)431 static void pgpFreeKeyDSA(pgpDigAlg pgpkey)
432 {
433     struct pgpDigKeyDSA_s *key = pgpkey->data;
434     if (key) {
435 	mpbfree(&key->p);
436 	mpbfree(&key->q);
437 	mpnfree(&key->g);
438 	mpnfree(&key->y);
439 	pgpkey->data = _free(key);
440     }
441 }
442 
443 
444 /****************************** NULL **************************************/
445 
pgpSetMpiNULL(pgpDigAlg pgpkey,int num,const uint8_t * p)446 static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num, const uint8_t *p)
447 {
448     return 1;
449 }
450 
pgpVerifyNULL(pgpDigAlg pgpkey,pgpDigAlg pgpsig,uint8_t * hash,size_t hashlen,int hash_algo)451 static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
452                          uint8_t *hash, size_t hashlen, int hash_algo)
453 {
454     return 1;
455 }
456 
pgpPubkeyNew(int algo,int curve)457 pgpDigAlg pgpPubkeyNew(int algo, int curve)
458 {
459     pgpDigAlg ka = xcalloc(1, sizeof(*ka));;
460 
461     switch (algo) {
462     case PGPPUBKEYALGO_RSA:
463         ka->setmpi = pgpSetKeyMpiRSA;
464         ka->free = pgpFreeKeyRSA;
465         ka->mpis = 2;
466         break;
467     case PGPPUBKEYALGO_DSA:
468         ka->setmpi = pgpSetKeyMpiDSA;
469         ka->free = pgpFreeKeyDSA;
470         ka->mpis = 4;
471         break;
472     default:
473         ka->setmpi = pgpSetMpiNULL;
474         ka->mpis = -1;
475         break;
476     }
477 
478     ka->verify = pgpVerifyNULL; /* keys can't be verified */
479 
480     return ka;
481 }
482 
pgpSignatureNew(int algo)483 pgpDigAlg pgpSignatureNew(int algo)
484 {
485     pgpDigAlg sa = xcalloc(1, sizeof(*sa));
486 
487     switch (algo) {
488     case PGPPUBKEYALGO_RSA:
489         sa->setmpi = pgpSetSigMpiRSA;
490         sa->free = pgpFreeSigRSA;
491         sa->verify = pgpVerifySigRSA;
492         sa->mpis = 1;
493         break;
494     case PGPPUBKEYALGO_DSA:
495         sa->setmpi = pgpSetSigMpiDSA;
496         sa->free = pgpFreeSigDSA;
497         sa->verify = pgpVerifySigDSA;
498         sa->mpis = 2;
499         break;
500     default:
501         sa->setmpi = pgpSetMpiNULL;
502         sa->verify = pgpVerifyNULL;
503         sa->mpis = -1;
504         break;
505     }
506     return sa;
507 }
508