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