1 #include "system.h"
2 
3 #include <gcrypt.h>
4 
5 #include <rpm/rpmpgp.h>
6 #include "rpmio/digest.h"
7 #include "rpmio/rpmio_internal.h"
8 #include "debug.h"
9 
10 /**
11  * MD5/SHA1 digest private data.
12  */
13 struct DIGEST_CTX_s {
14     rpmDigestFlags flags;	/*!< Bit(s) to control digest operation. */
15     int algo;			/*!< Used hash algorithm */
16     gcry_md_hd_t h;
17 };
18 
19 
20 /****************************  init   ************************************/
21 
rpmInitCrypto(void)22 int rpmInitCrypto(void) {
23     gcry_check_version (NULL);
24     gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
25     return 0;
26 }
27 
rpmFreeCrypto(void)28 int rpmFreeCrypto(void) {
29     return 0;
30 }
31 
32 /****************************  digest ************************************/
33 
rpmDigestLength(int hashalgo)34 size_t rpmDigestLength(int hashalgo)
35 {
36     switch (hashalgo) {
37     case PGPHASHALGO_MD5:
38 	return 16;
39     case PGPHASHALGO_SHA1:
40 	return 20;
41     case PGPHASHALGO_SHA224:
42 	return 28;
43     case PGPHASHALGO_SHA256:
44 	return 32;
45     case PGPHASHALGO_SHA384:
46 	return 48;
47     case PGPHASHALGO_SHA512:
48 	return 64;
49     default:
50 	return 0;
51     }
52 }
53 
hashalgo2gcryalgo(int hashalgo)54 static int hashalgo2gcryalgo(int hashalgo)
55 {
56     switch (hashalgo) {
57     case PGPHASHALGO_MD5:
58 	return GCRY_MD_MD5;
59     case PGPHASHALGO_SHA1:
60 	return GCRY_MD_SHA1;
61     case PGPHASHALGO_SHA224:
62 	return GCRY_MD_SHA224;
63     case PGPHASHALGO_SHA256:
64 	return GCRY_MD_SHA256;
65     case PGPHASHALGO_SHA384:
66 	return GCRY_MD_SHA384;
67     case PGPHASHALGO_SHA512:
68 	return GCRY_MD_SHA512;
69     default:
70 	return 0;
71     }
72 }
73 
rpmDigestInit(int hashalgo,rpmDigestFlags flags)74 DIGEST_CTX rpmDigestInit(int hashalgo, rpmDigestFlags flags)
75 {
76     gcry_md_hd_t h;
77     DIGEST_CTX ctx;
78     int gcryalgo = hashalgo2gcryalgo(hashalgo);
79 
80     if (!gcryalgo || gcry_md_open(&h, gcryalgo, 0) != 0)
81 	return NULL;
82 
83     ctx = xcalloc(1, sizeof(*ctx));
84     ctx->flags = flags;
85     ctx->algo = hashalgo;
86     ctx->h = h;
87     return ctx;
88 }
89 
rpmDigestUpdate(DIGEST_CTX ctx,const void * data,size_t len)90 int rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
91 {
92     if (ctx == NULL)
93 	return -1;
94     gcry_md_write(ctx->h, data, len);
95     return 0;
96 }
97 
rpmDigestFinal(DIGEST_CTX ctx,void ** datap,size_t * lenp,int asAscii)98 int rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
99 {
100     unsigned char *digest;
101     int digestlen;
102     if (ctx == NULL)
103 	return -1;
104     digest = gcry_md_read(ctx->h, 0);
105     digestlen = rpmDigestLength(ctx->algo);
106     if (!asAscii) {
107 	if (lenp)
108 	    *lenp = digestlen;
109 	if (datap) {
110 	    *datap = xmalloc(digestlen);
111 	    memcpy(*datap, digest, digestlen);
112 	}
113     } else {
114 	if (lenp)
115 	    *lenp = 2 * digestlen + 1;
116 	if (datap) {
117 	    *datap = pgpHexStr((const uint8_t *)digest, digestlen);
118 	}
119     }
120     gcry_md_close(ctx->h);
121     free(ctx);
122     return 0;
123 }
124 
rpmDigestDup(DIGEST_CTX octx)125 DIGEST_CTX rpmDigestDup(DIGEST_CTX octx)
126 {
127     DIGEST_CTX nctx = NULL;
128     if (octx) {
129         gcry_md_hd_t h;
130 	if (gcry_md_copy(&h, octx->h))
131 	    return NULL;
132 	nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
133 	nctx->h = h;
134     }
135     return nctx;
136 }
137 
138 
139 /****************************** RSA **************************************/
140 
141 struct pgpDigSigRSA_s {
142     gcry_mpi_t s;
143 };
144 
145 struct pgpDigKeyRSA_s {
146     gcry_mpi_t n;
147     gcry_mpi_t e;
148 };
149 
pgpSetSigMpiRSA(pgpDigAlg pgpsig,int num,const uint8_t * p)150 static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num, const uint8_t *p)
151 {
152     struct pgpDigSigRSA_s *sig = pgpsig->data;
153     int mlen = pgpMpiLen(p);
154     int rc = 1;
155 
156     if (!sig)
157 	sig = pgpsig->data = xcalloc(1, sizeof(*sig));
158 
159     switch (num) {
160     case 0:
161 	if (!gcry_mpi_scan(&sig->s, GCRYMPI_FMT_PGP, p, mlen, NULL))
162 	    rc = 0;
163 	break;
164     }
165     return rc;
166 }
167 
pgpSetKeyMpiRSA(pgpDigAlg pgpkey,int num,const uint8_t * p)168 static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
169 {
170     struct pgpDigKeyRSA_s *key = pgpkey->data;
171     int mlen = pgpMpiLen(p);
172     int rc = 1;
173 
174     if (!key)
175 	key = pgpkey->data = xcalloc(1, sizeof(*key));
176 
177     switch (num) {
178     case 0:
179 	if (!gcry_mpi_scan(&key->n, GCRYMPI_FMT_PGP, p, mlen, NULL))
180 	    rc = 0;
181 	break;
182     case 1:
183 	if (!gcry_mpi_scan(&key->e, GCRYMPI_FMT_PGP, p, mlen, NULL))
184 	    rc = 0;
185 	break;
186     }
187     return rc;
188 }
189 
pgpVerifySigRSA(pgpDigAlg pgpkey,pgpDigAlg pgpsig,uint8_t * hash,size_t hashlen,int hash_algo)190 static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo)
191 {
192     struct pgpDigKeyRSA_s *key = pgpkey->data;
193     struct pgpDigSigRSA_s *sig = pgpsig->data;
194     gcry_sexp_t sexp_sig = NULL, sexp_data = NULL, sexp_pkey = NULL;
195     const char *hash_algo_name;
196     int rc = 1;
197 
198     if (!sig || !key)
199 	return rc;
200 
201     hash_algo_name = gcry_md_algo_name(hashalgo2gcryalgo(hash_algo));
202     gcry_sexp_build(&sexp_sig, NULL, "(sig-val (rsa (s %M)))", sig->s);
203     gcry_sexp_build(&sexp_data, NULL, "(data (flags pkcs1) (hash %s %b))", hash_algo_name, (int)hashlen, (const char *)hash);
204     gcry_sexp_build(&sexp_pkey, NULL, "(public-key (rsa (n %M) (e %M)))", key->n, key->e);
205     if (sexp_sig && sexp_data && sexp_pkey)
206 	rc = gcry_pk_verify(sexp_sig, sexp_data, sexp_pkey) == 0 ? 0 : 1;
207     gcry_sexp_release(sexp_sig);
208     gcry_sexp_release(sexp_data);
209     gcry_sexp_release(sexp_pkey);
210     return rc;
211 }
212 
pgpFreeSigRSA(pgpDigAlg pgpsig)213 static void pgpFreeSigRSA(pgpDigAlg pgpsig)
214 {
215     struct pgpDigSigRSA_s *sig = pgpsig->data;
216     if (sig) {
217         gcry_mpi_release(sig->s);
218 	pgpsig->data = _free(sig);
219     }
220 }
221 
pgpFreeKeyRSA(pgpDigAlg pgpkey)222 static void pgpFreeKeyRSA(pgpDigAlg pgpkey)
223 {
224     struct pgpDigKeyRSA_s *key = pgpkey->data;
225     if (key) {
226         gcry_mpi_release(key->n);
227         gcry_mpi_release(key->e);
228 	pgpkey->data = _free(key);
229     }
230 }
231 
232 
233 /****************************** DSA **************************************/
234 
235 struct pgpDigSigDSA_s {
236     gcry_mpi_t r;
237     gcry_mpi_t s;
238 };
239 
240 struct pgpDigKeyDSA_s {
241     gcry_mpi_t p;
242     gcry_mpi_t q;
243     gcry_mpi_t g;
244     gcry_mpi_t y;
245 };
246 
pgpSetSigMpiDSA(pgpDigAlg pgpsig,int num,const uint8_t * p)247 static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num, const uint8_t *p)
248 {
249     struct pgpDigSigDSA_s *sig = pgpsig->data;
250     int mlen = pgpMpiLen(p);
251     int rc = 1;
252 
253     if (!sig)
254 	sig = pgpsig->data = xcalloc(1, sizeof(*sig));
255 
256     switch (num) {
257     case 0:
258 	if (!gcry_mpi_scan(&sig->r, GCRYMPI_FMT_PGP, p, mlen, NULL))
259 	    rc = 0;
260 	break;
261     case 1:
262 	if (!gcry_mpi_scan(&sig->s, GCRYMPI_FMT_PGP, p, mlen, NULL))
263 	    rc = 0;
264 	break;
265     }
266     return rc;
267 }
268 
pgpSetKeyMpiDSA(pgpDigAlg pgpkey,int num,const uint8_t * p)269 static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
270 {
271     struct pgpDigKeyDSA_s *key = pgpkey->data;
272     int mlen = pgpMpiLen(p);
273     int rc = 1;
274 
275     if (!key)
276 	key = pgpkey->data = xcalloc(1, sizeof(*key));
277 
278     switch (num) {
279     case 0:
280 	if (!gcry_mpi_scan(&key->p, GCRYMPI_FMT_PGP, p, mlen, NULL))
281 	    rc = 0;
282 	break;
283     case 1:
284 	if (!gcry_mpi_scan(&key->q, GCRYMPI_FMT_PGP, p, mlen, NULL))
285 	    rc = 0;
286 	break;
287     case 2:
288 	if (!gcry_mpi_scan(&key->g, GCRYMPI_FMT_PGP, p, mlen, NULL))
289 	    rc = 0;
290 	break;
291     case 3:
292 	if (!gcry_mpi_scan(&key->y, GCRYMPI_FMT_PGP, p, mlen, NULL))
293 	    rc = 0;
294 	break;
295     }
296     return rc;
297 }
298 
pgpVerifySigDSA(pgpDigAlg pgpkey,pgpDigAlg pgpsig,uint8_t * hash,size_t hashlen,int hash_algo)299 static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo)
300 {
301     struct pgpDigKeyDSA_s *key = pgpkey->data;
302     struct pgpDigSigDSA_s *sig = pgpsig->data;
303     gcry_sexp_t sexp_sig = NULL, sexp_data = NULL, sexp_pkey = NULL;
304     int rc = 1;
305     size_t qlen;
306 
307     if (!sig || !key)
308 	return rc;
309 
310     qlen = (mpi_get_nbits(key->q) + 7) / 8;
311     if (qlen < 20)
312 	qlen = 20;		/* sanity */
313     if (hashlen > qlen)
314 	hashlen = qlen;		/* dsa2: truncate hash to qlen */
315     gcry_sexp_build(&sexp_sig, NULL, "(sig-val (dsa (r %M) (s %M)))", sig->r, sig->s);
316     gcry_sexp_build(&sexp_data, NULL, "(data (flags raw) (value %b))", (int)hashlen, (const char *)hash);
317     gcry_sexp_build(&sexp_pkey, NULL, "(public-key (dsa (p %M) (q %M) (g %M) (y %M)))", key->p, key->q, key->g, key->y);
318     if (sexp_sig && sexp_data && sexp_pkey)
319 	rc = gcry_pk_verify(sexp_sig, sexp_data, sexp_pkey) == 0 ? 0 : 1;
320     gcry_sexp_release(sexp_sig);
321     gcry_sexp_release(sexp_data);
322     gcry_sexp_release(sexp_pkey);
323     return rc;
324 }
325 
pgpFreeSigDSA(pgpDigAlg pgpsig)326 static void pgpFreeSigDSA(pgpDigAlg pgpsig)
327 {
328     struct pgpDigSigDSA_s *sig = pgpsig->data;
329     if (sig) {
330         gcry_mpi_release(sig->r);
331         gcry_mpi_release(sig->s);
332 	pgpsig->data = _free(sig);
333     }
334 }
335 
pgpFreeKeyDSA(pgpDigAlg pgpkey)336 static void pgpFreeKeyDSA(pgpDigAlg pgpkey)
337 {
338     struct pgpDigKeyDSA_s *key = pgpkey->data;
339     if (key) {
340         gcry_mpi_release(key->p);
341         gcry_mpi_release(key->q);
342         gcry_mpi_release(key->g);
343         gcry_mpi_release(key->y);
344 	pgpkey->data = _free(key);
345     }
346 }
347 
348 
349 /****************************** EDDSA **************************************/
350 
351 struct pgpDigSigEDDSA_s {
352     gcry_mpi_t r;
353     gcry_mpi_t s;
354 };
355 
356 struct pgpDigKeyEDDSA_s {
357     gcry_mpi_t q;
358 };
359 
pgpSetSigMpiEDDSA(pgpDigAlg pgpsig,int num,const uint8_t * p)360 static int pgpSetSigMpiEDDSA(pgpDigAlg pgpsig, int num, const uint8_t *p)
361 {
362     struct pgpDigSigEDDSA_s *sig = pgpsig->data;
363     int mlen = pgpMpiLen(p);
364     int rc = 1;
365 
366     if (!sig)
367 	sig = pgpsig->data = xcalloc(1, sizeof(*sig));
368 
369     switch (num) {
370     case 0:
371 	if (!gcry_mpi_scan(&sig->r, GCRYMPI_FMT_PGP, p, mlen, NULL))
372 	    rc = 0;
373 	break;
374     case 1:
375 	if (!gcry_mpi_scan(&sig->s, GCRYMPI_FMT_PGP, p, mlen, NULL))
376 	    rc = 0;
377 	break;
378     }
379     return rc;
380 }
381 
pgpSetKeyMpiEDDSA(pgpDigAlg pgpkey,int num,const uint8_t * p)382 static int pgpSetKeyMpiEDDSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
383 {
384     struct pgpDigKeyEDDSA_s *key = pgpkey->data;
385     int mlen = pgpMpiLen(p);
386     int rc = 1;
387 
388     if (!key)
389 	key = pgpkey->data = xcalloc(1, sizeof(*key));
390 
391     switch (num) {
392     case 0:
393 	if (!gcry_mpi_scan(&key->q, GCRYMPI_FMT_PGP, p, mlen, NULL))
394 	    rc = 0;
395 	break;
396     }
397     return rc;
398 }
399 
400 static int
ed25519_zero_extend(gcry_mpi_t x,unsigned char * buf,int bufl)401 ed25519_zero_extend(gcry_mpi_t x, unsigned char *buf, int bufl)
402 {
403     int n = (gcry_mpi_get_nbits(x) + 7) / 8;
404     if (n == 0 || n > bufl)
405 	return 1;
406     n = bufl - n;
407     if (n)
408 	memset(buf, 0, n);
409     gcry_mpi_print(GCRYMPI_FMT_USG, buf + n, bufl - n, NULL, x);
410     return 0;
411 }
412 
pgpVerifySigEDDSA(pgpDigAlg pgpkey,pgpDigAlg pgpsig,uint8_t * hash,size_t hashlen,int hash_algo)413 static int pgpVerifySigEDDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo)
414 {
415     struct pgpDigKeyEDDSA_s *key = pgpkey->data;
416     struct pgpDigSigEDDSA_s *sig = pgpsig->data;
417     gcry_sexp_t sexp_sig = NULL, sexp_data = NULL, sexp_pkey = NULL;
418     int rc = 1;
419     unsigned char buf_r[32], buf_s[32];
420 
421     if (!sig || !key)
422 	return rc;
423     if (pgpkey->curve != PGPCURVE_ED25519)
424 	return rc;
425     if (hash_algo != PGPHASHALGO_SHA256)
426 	return rc;
427     if (ed25519_zero_extend(sig->r, buf_r, 32) || ed25519_zero_extend(sig->s, buf_s, 32))
428 	return rc;
429     gcry_sexp_build(&sexp_sig, NULL, "(sig-val (eddsa (r %b) (s %b)))", 32, (const char *)buf_r, 32, (const char *)buf_s, 32);
430     gcry_sexp_build(&sexp_data, NULL, "(data (flags eddsa) (hash-algo sha512) (value %b))", (int)hashlen, (const char *)hash);
431     gcry_sexp_build(&sexp_pkey, NULL, "(public-key (ecc (curve \"Ed25519\") (flags eddsa) (q %M)))", key->q);
432     if (sexp_sig && sexp_data && sexp_pkey)
433 	rc = gcry_pk_verify(sexp_sig, sexp_data, sexp_pkey) == 0 ? 0 : 1;
434     gcry_sexp_release(sexp_sig);
435     gcry_sexp_release(sexp_data);
436     gcry_sexp_release(sexp_pkey);
437     return rc;
438 }
439 
pgpFreeSigEDDSA(pgpDigAlg pgpsig)440 static void pgpFreeSigEDDSA(pgpDigAlg pgpsig)
441 {
442     struct pgpDigSigEDDSA_s *sig = pgpsig->data;
443     if (sig) {
444 	gcry_mpi_release(sig->r);
445 	gcry_mpi_release(sig->s);
446 	pgpsig->data = _free(sig);
447     }
448 }
449 
pgpFreeKeyEDDSA(pgpDigAlg pgpkey)450 static void pgpFreeKeyEDDSA(pgpDigAlg pgpkey)
451 {
452     struct pgpDigKeyEDDSA_s *key = pgpkey->data;
453     if (key) {
454 	gcry_mpi_release(key->q);
455 	pgpkey->data = _free(key);
456     }
457 }
458 
459 
460 /****************************** NULL **************************************/
461 
pgpSetMpiNULL(pgpDigAlg pgpkey,int num,const uint8_t * p)462 static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num, const uint8_t *p)
463 {
464     return 1;
465 }
466 
pgpVerifyNULL(pgpDigAlg pgpkey,pgpDigAlg pgpsig,uint8_t * hash,size_t hashlen,int hash_algo)467 static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
468                          uint8_t *hash, size_t hashlen, int hash_algo)
469 {
470     return 1;
471 }
472 
pgpSupportedCurve(int curve)473 static int pgpSupportedCurve(int curve)
474 {
475     if (curve == PGPCURVE_ED25519) {
476 	static int supported_ed25519;
477 	if (!supported_ed25519) {
478 	    gcry_sexp_t sexp = NULL;
479 	    unsigned int nbits;
480 	    gcry_sexp_build(&sexp, NULL, "(public-key (ecc (curve \"Ed25519\")))");
481 	    nbits = gcry_pk_get_nbits(sexp);
482 	    gcry_sexp_release(sexp);
483 	    supported_ed25519 = nbits > 0 ? 1 : -1;
484 	}
485 	return supported_ed25519 > 0;
486     }
487     return 0;
488 }
489 
pgpPubkeyNew(int algo,int curve)490 pgpDigAlg pgpPubkeyNew(int algo, int curve)
491 {
492     pgpDigAlg ka = xcalloc(1, sizeof(*ka));;
493 
494     switch (algo) {
495     case PGPPUBKEYALGO_RSA:
496         ka->setmpi = pgpSetKeyMpiRSA;
497         ka->free = pgpFreeKeyRSA;
498         ka->mpis = 2;
499         break;
500     case PGPPUBKEYALGO_DSA:
501         ka->setmpi = pgpSetKeyMpiDSA;
502         ka->free = pgpFreeKeyDSA;
503         ka->mpis = 4;
504         break;
505     case PGPPUBKEYALGO_EDDSA:
506 	if (!pgpSupportedCurve(curve)) {
507 	    ka->setmpi = pgpSetMpiNULL;
508 	    ka->mpis = -1;
509 	    break;
510 	}
511         ka->setmpi = pgpSetKeyMpiEDDSA;
512         ka->free = pgpFreeKeyEDDSA;
513         ka->mpis = 1;
514         ka->curve = curve;
515         break;
516     default:
517         ka->setmpi = pgpSetMpiNULL;
518         ka->mpis = -1;
519         break;
520     }
521 
522     ka->verify = pgpVerifyNULL; /* keys can't be verified */
523 
524     return ka;
525 }
526 
pgpSignatureNew(int algo)527 pgpDigAlg pgpSignatureNew(int algo)
528 {
529     pgpDigAlg sa = xcalloc(1, sizeof(*sa));
530 
531     switch (algo) {
532     case PGPPUBKEYALGO_RSA:
533         sa->setmpi = pgpSetSigMpiRSA;
534         sa->free = pgpFreeSigRSA;
535         sa->verify = pgpVerifySigRSA;
536         sa->mpis = 1;
537         break;
538     case PGPPUBKEYALGO_DSA:
539         sa->setmpi = pgpSetSigMpiDSA;
540         sa->free = pgpFreeSigDSA;
541         sa->verify = pgpVerifySigDSA;
542         sa->mpis = 2;
543         break;
544     case PGPPUBKEYALGO_EDDSA:
545         sa->setmpi = pgpSetSigMpiEDDSA;
546         sa->free = pgpFreeSigEDDSA;
547         sa->verify = pgpVerifySigEDDSA;
548         sa->mpis = 2;
549         break;
550     default:
551         sa->setmpi = pgpSetMpiNULL;
552         sa->verify = pgpVerifyNULL;
553         sa->mpis = -1;
554         break;
555     }
556     return sa;
557 }
558