10 #define _RPMPGP_INTERNAL
11 #if defined(WITH_TOMCRYPT)
12 #define _RPMLTC_INTERNAL
18 #if defined(WITH_TOMCRYPT)
32 static int _rpmltc_debug;
35 static prng_state prng;
37 #define SPEW(_t, _rc, _dig) \
38 { if ((_t) || _rpmltc_debug || _pgp_debug < 0) \
39 fprintf(stderr, "<-- %s(%p) %s\t%s/%s\n", __FUNCTION__, (_dig), \
40 ((_rc) ? "OK" : "BAD"), (_dig)->pubkey_algoN, (_dig)->hash_algoN); \
49 unsigned char nibble(
char c)
52 if (c >=
'0' && c <=
'9')
53 return (
unsigned char) (c -
'0');
54 if (c >=
'A' && c <=
'F')
55 return (
unsigned char)((int)(c -
'A') + 10);
56 if (c >=
'a' && c <=
'f')
57 return (
unsigned char)((int)(c -
'a') + 10);
58 return (
unsigned char)
'\0';
62 int rpmltcErr(
rpmltc ltc,
const char * msg,
int rc)
67 fprintf (stderr,
"rpmltc: %s rc(%d) %s\n",
68 msg, rc, error_to_string(rc));
74 #define _spewBN(_N, _BN) \
75 { mp_int * bn = _BN; \
77 int err = (bn ? mp_radix_size(bn, 16, &nt) : 0); \
78 char * t = (nt ? xmalloc(nt) : ""); \
80 err = mp_toradix(bn, t, 16); \
81 fprintf(stderr, "\t" _N ": %s\n", t); \
86 static void rpmltcDumpRSA(
const char * msg,
rpmltc ltc)
88 if (msg) fprintf(stderr,
"========== %s\n", msg);
91 _spewBN(
" n", ltc->rsa.N);
92 _spewBN(
" e", ltc->rsa.e);
93 _spewBN(
" d", ltc->rsa.d);
94 _spewBN(
" p", ltc->rsa.p);
95 _spewBN(
" q", ltc->rsa.q);
96 _spewBN(
"dp", ltc->rsa.dP);
97 _spewBN(
"dq", ltc->rsa.dQ);
98 _spewBN(
"qi", ltc->rsa.qP);
101 _spewBN(
" c", ltc->c);
104 static void rpmltcDumpDSA(
const char * msg,
rpmltc ltc)
106 if (msg) fprintf(stderr,
"========== %s\n", msg);
109 _spewBN(
" p", ltc->dsa.p);
110 _spewBN(
" q", ltc->dsa.q);
111 _spewBN(
" g", ltc->dsa.g);
112 _spewBN(
" x", ltc->dsa.x);
113 _spewBN(
" y", ltc->dsa.y);
116 _spewBN(
" r", ltc->r);
117 _spewBN(
" s", ltc->s);
121 static void rpmltcDumpECDSA(
const char * msg,
rpmltc ltc)
123 if (msg) fprintf(stderr,
"========== %s\n", msg);
126 const ltc_ecc_set_type * dp = ltc->ecdsa.idx >= 0
127 ? ltc_ecc_sets + ltc->ecdsa.idx : NULL;
132 fprintf(stderr,
"\tsize: %d\n", dp->size);
133 fprintf(stderr,
"\tname: %s\n", dp->name);
134 fprintf(stderr,
"\t p: %s\n", dp->prime);
135 fprintf(stderr,
"\t n: %s\n", dp->order);
136 fprintf(stderr,
"\t b: %s\n", dp->B);
137 fprintf(stderr,
"\tGx: %s\n", dp->Gx);
138 fprintf(stderr,
"\tGy: %s\n", dp->Gy);
141 _spewBN(
"Qx", ltc->ecdsa.pubkey.x);
142 _spewBN(
"Qy", ltc->ecdsa.pubkey.y);
144 _spewBN(
" d", ltc->ecdsa.k);
148 _spewBN(
" r", ltc->r);
149 _spewBN(
" s", ltc->s);
156 static int getHashIdx(
unsigned hash_algo)
158 const char * hashN = NULL;
175 case PGPHASHALGO_WHIRLPOOL: hashN =
"whirlpool";
break;
181 return (hashN ? find_hash(hashN) : -1);
185 #define _initBN(_t) \
186 { if (_t == NULL) _t = xmalloc(sizeof(mp_int)); \
205 ltc->digest =
_free(ltc->digest);
207 xx =
rpmDigestFinal(ctx, (
void **)<c->digest, <c->digestlen, 0);
209 ltc->hashIdx = getHashIdx(sigp->hash_algo);
210 if (ltc->hashIdx < 0)
214 rc = memcmp(ltc->digest, sigp->signhash16,
sizeof(sigp->signhash16));
217 if (rc && sigp->signhash16[0] == 0 && sigp->signhash16[1] == 0)
240 ltc->digest =
_free(ltc->digest);
242 xx =
rpmDigestFinal(ctx, (
void **)<c->digest, <c->digestlen, 0);
244 ltc->hashIdx = getHashIdx(sigp->hash_algo);
245 if (ltc->hashIdx < 0)
249 rc = memcmp(ltc->digest, sigp->signhash16,
sizeof(sigp->signhash16));
251 if (rc && sigp->signhash16[0] == 0 && sigp->signhash16[1] == 0)
274 ltc->digest =
_free(ltc->digest);
276 xx =
rpmDigestFinal(ctx, (
void **)<c->digest, <c->digestlen, 0);
278 ltc->hashIdx = getHashIdx(sigp->hash_algo);
279 if (ltc->hashIdx < 0)
283 rc = memcmp(ltc->digest, sigp->signhash16,
sizeof(sigp->signhash16));
285 if (rc && sigp->signhash16[0] == 0 && sigp->signhash16[1] == 0)
311 ltc->digest =
_free(ltc->digest);
315 ltc->hashIdx = getHashIdx(sigp->hash_algo);
316 if (ltc->hashIdx < 0)
320 rc = memcmp(ltc->digest, sigp->signhash16,
sizeof(sigp->signhash16));
322 if (rc && sigp->signhash16[0] == 0 && sigp->signhash16[1] == 0)
330 static int rpmltcErrChk(
pgpDig dig,
const char * msg,
int rc,
unsigned expected)
333 rpmgc gc = dig->impl;
335 rc = (gcry_err_code(gc->err) != expected);
337 fail(
"%s failed: %s\n", msg, gpg_strerror(gc->err));
345 static int rpmltcAvailableCipher(
pgpDig dig,
int algo)
349 rc = rpmgcAvailable(dig->impl, algo,
355 static int rpmltcAvailableDigest(
pgpDig dig,
int algo)
359 rc = rpmgcAvailable(dig->impl, algo,
365 static int rpmltcAvailablePubkey(
pgpDig dig,
int algo)
369 rc = rpmgcAvailable(dig->impl, algo, gcry_pk_test_algo(algo));
374 static int rpmltcVerify(
pgpDig dig)
378 unsigned char sig[4096];
379 unsigned long siglen =
sizeof(sig);
381 int _padding = LTC_LTC_PKCS_1_V1_5;
382 unsigned long saltlen = 0;
390 assert(ltc->digest && ltc->digestlen > 0);
393 switch (pubp->pubkey_algo) {
398 assert(ltc->hashIdx >= 0);
399 siglen = ltc->nbits/8;
400 nz = siglen - mp_unsigned_bin_size(ltc->c);
403 xx = mp_to_unsigned_bin(ltc->c, sig+nz);
404 xx = rpmltcErr(ltc,
"rsa_verify_hash_ex",
405 rsa_verify_hash_ex(sig, siglen,
406 ltc->digest, ltc->digestlen,
407 _padding, ltc->hashIdx, saltlen, &rc, <c->rsa));
410 assert(ltc->r && ltc->s);
413 dlen = (ltc->digestlen > ltc->qbits/8 ? ltc->qbits/8 : ltc->digestlen);
414 xx = rpmltcErr(ltc,
"dsa_verify_hash_raw",
415 dsa_verify_hash_raw(ltc->r, ltc->s,
416 ltc->digest, dlen, &rc, <c->dsa));
420 rc = rpmltcVerifyELG(dig);
424 assert(ltc->r && ltc->s);
425 xx = der_encode_sequence_multi(sig, &siglen,
426 LTC_ASN1_INTEGER, 1UL, ltc->r,
427 LTC_ASN1_INTEGER, 1UL, ltc->s,
428 LTC_ASN1_EOL, 0UL, NULL);
429 xx = rpmltcErr(ltc,
"ecc_verify_hash",
430 ecc_verify_hash(sig, siglen,
431 ltc->digest, ltc->digestlen, &rc, <c->ecdsa));
439 static int rpmltcSign(
pgpDig dig)
443 unsigned char sig[2048];
444 unsigned long siglen =
sizeof(sig);
446 int _padding = LTC_LTC_PKCS_1_V1_5;
447 unsigned long saltlen = 0 ;
452 assert(ltc->digest && ltc->digestlen > 0);
454 switch (pubp->pubkey_algo) {
458 assert(ltc->hashIdx >= 0);
459 rc = rpmltcErr(ltc,
"rsa_sign_hash_ex",
460 rsa_sign_hash_ex(ltc->digest, ltc->digestlen, sig, &siglen,
461 _padding, &prng, ltc->prngIdx,
462 ltc->hashIdx, saltlen, <c->rsa));
463 if (rc == CRYPT_OK) {
465 xx = mp_read_unsigned_bin(ltc->c, sig, siglen);
473 dlen = (ltc->digestlen > ltc->qbits/8 ? ltc->qbits/8 : ltc->digestlen);
474 rc = rpmltcErr(ltc,
"dsa_sign_hash_raw",
475 dsa_sign_hash_raw(ltc->digest, dlen, ltc->r, ltc->s,
476 &prng, ltc->prngIdx, <c->dsa));
480 rc = rpmltcSignELG(dig);
484 rc = rpmltcErr(ltc,
"ecc_sign_hash",
485 ecc_sign_hash(ltc->digest, ltc->digestlen, sig, &siglen,
486 &prng, ltc->prngIdx, <c->ecdsa));
487 if (rc == CRYPT_OK) {
490 xx = der_decode_sequence_multi(sig, siglen,
491 LTC_ASN1_INTEGER, 1UL, ltc->r,
492 LTC_ASN1_INTEGER, 1UL, ltc->s,
493 LTC_ASN1_EOL, 0UL, NULL);
498 rc = (rc == CRYPT_OK);
504 static int rpmltcGenerate(
pgpDig dig)
510 assert(pubp->pubkey_algo);
511 assert(sigp->hash_algo);
513 assert(dig->pubkey_algoN);
514 assert(dig->hash_algoN);
516 switch (pubp->pubkey_algo) {
521 static long _e = 0x10001;
522 if (ltc->nbits == 0) ltc->nbits = 2048;
523 rc = rpmltcErr(ltc,
"rsa_make_key",
524 rsa_make_key(&prng, ltc->prngIdx,
525 ltc->nbits/8, _e, <c->rsa));
526 rc = (rc == CRYPT_OK);
536 switch (sigp->hash_algo) {
548 switch (ltc->qbits) {
550 case 160: ltc->nbits = 1024;
break;
551 case 224: ltc->nbits = 2048;
break;
553 case 256: ltc->nbits = 3072;
break;
554 case 384: ltc->nbits = 7680;
break;
555 case 512: ltc->nbits = 15360;
break;
557 case 256: ltc->nbits = 2048;
break;
558 case 384: ltc->nbits = 2048; ltc->qbits = 256;
break;
559 case 512: ltc->nbits = 2048; ltc->qbits = 256;
break;
564 _group_size = ltc->qbits/8;
565 _modulus_size = ltc->nbits/8;
567 xx = rpmltcErr(ltc,
"dsa_make_key",
568 dsa_make_key(&prng, ltc->prngIdx,
569 _group_size, _modulus_size, <c->dsa));
572 xx = rpmltcErr(ltc,
"dsa_verify_key",
573 dsa_verify_key(<c->dsa, &rc));
577 rc = rpmltcGenerateELG(dig);
583 switch (sigp->hash_algo) {
595 rc = rpmltcErr(ltc,
"ecc_make_key",
596 ecc_make_key(&prng, ltc->prngIdx,
597 ltc->nbits/8, <c->ecdsa));
598 rc = (rc == CRYPT_OK);
606 #define _loadBN(_t, _s, _ns) \
609 xx = mp_read_unsigned_bin(_t, _s, _ns); \
613 int rpmltcMpiItem(
const char * pre,
pgpDig dig,
int itemno,
619 unsigned int nb = (pend >= p ? (pend - p) : 0);
620 unsigned int mbits = (((8 * (nb - 2)) + 0x1f) & ~0x1f);
629 _loadBN(ltc->c, p+2, nb-2);
633 _loadBN(ltc->r, p+2, nb-2);
636 assert(mbits == ltc->qbits);
637 _loadBN(ltc->s, p+2, nb-2);
641 _loadBN(ltc->rsa.N, p+2, nb-2);
644 _loadBN(ltc->rsa.e, p+2, nb-2);
648 _loadBN(ltc->dsa.p, p+2, nb-2);
652 _loadBN(ltc->dsa.q, p+2, nb-2);
655 assert(mbits == ltc->nbits);
656 _loadBN(ltc->dsa.g, p+2, nb-2);
659 assert(mbits == ltc->nbits);
660 _loadBN(ltc->dsa.y, p+2, nb-2);
664 _loadBN(ltc->r, p+2, nb-2);
667 assert(mbits == ltc->qbits);
668 _loadBN(ltc->s, p+2, nb-2);
672 if (!strcasecmp(s,
"2a8648ce3d030101"))
674 else if (!strcasecmp(s,
"2b81040021"))
676 else if (!strcasecmp(s,
"2a8648ce3d030107"))
678 else if (!strcasecmp(s,
"2b81040022"))
680 else if (!strcasecmp(s,
"2b81040023"))
686 assert(ltc->nbits > 0);
691 rc = ecc_ansi_x963_import(p+2, nb-2, <c->ecdsa);
692 assert(rc == CRYPT_OK);
701 #define _freeBN(_t) \
703 (void) mp_clear(_t); \
708 void rpmltcClean(
void * impl)
717 ltc->digest =
_free(ltc->digest);
726 _freeBN(ltc->rsa.dP);
727 _freeBN(ltc->rsa.dQ);
728 _freeBN(ltc->rsa.qP);
729 memset(<c->rsa, 0,
sizeof(ltc->rsa));
739 memset(<c->dsa, 0,
sizeof(ltc->dsa));
744 ecc_free(<c->ecdsa);
745 memset(<c->ecdsa, 0,
sizeof(ltc->ecdsa));
753 void * rpmltcFree(
void * impl)
761 static void reg_algs(
rpmltc ltc)
765 register_cipher (&aes_desc);
768 register_cipher (&blowfish_desc);
771 register_cipher (&xtea_desc);
774 register_cipher (&rc5_desc);
777 register_cipher (&rc6_desc);
780 register_cipher (&saferp_desc);
783 register_cipher (&twofish_desc);
786 register_cipher (&safer_k64_desc);
787 register_cipher (&safer_sk64_desc);
788 register_cipher (&safer_k128_desc);
789 register_cipher (&safer_sk128_desc);
792 register_cipher (&rc2_desc);
795 register_cipher (&des_desc);
796 register_cipher (&des3_desc);
799 register_cipher (&cast5_desc);
802 register_cipher (&noekeon_desc);
805 register_cipher (&skipjack_desc);
808 register_cipher (&khazad_desc);
811 register_cipher (&anubis_desc);
814 register_cipher (&kseed_desc);
817 register_cipher (&kasumi_desc);
820 register_cipher (&multi2_desc);
824 register_hash (&tiger_desc);
827 register_hash (&md2_desc);
830 register_hash (&md4_desc);
833 register_hash (&md5_desc);
836 register_hash (&sha1_desc);
839 register_hash (&sha224_desc);
842 register_hash (&sha256_desc);
845 register_hash (&sha384_desc);
848 register_hash (&sha512_desc);
851 register_hash (&rmd128_desc);
854 register_hash (&rmd160_desc);
857 register_hash (&rmd256_desc);
860 register_hash (&rmd320_desc);
863 register_hash (&whirlpool_desc);
866 register_hash(&chc_desc);
867 err = rpmltcErr(ltc,
"chc_register",
868 chc_register(register_cipher(&aes_desc)));
873 register_prng(&yarrow_desc);
875 register_prng(&fortuna_desc);
878 register_prng(&rc4_desc);
881 register_prng(&sober128_desc);
885 err = rpmltcErr(ltc,
"rng_make_prng",
886 rng_make_prng(128, find_prng(
"fortuna"), &prng, NULL));
888 err = rpmltcErr(ltc,
"rng_make_prng",
889 rng_make_prng(128, find_prng(
"yarrow"), &prng, NULL));
896 void * rpmltcInit(
void)
903 #if defined(LTM_DESC)
910 ltc->prngIdx = find_prng(
"fortuna");
912 ltc->prngIdx = find_prng(
"yarrow");
926 rpmltcAvailableCipher, rpmltcAvailableDigest, rpmltcAvailablePubkey,
927 rpmltcVerify, rpmltcSign, rpmltcGenerate,
929 rpmltcMpiItem, rpmltcClean,
930 rpmltcFree, rpmltcInit
938 time_t now =
time(NULL);
954 *be++ = pubp->pubkey_algo;
956 switch (pubp->pubkey_algo) {
961 bn = mp_count_bits(ltc->rsa.N);
962 *be++ = (bn >> 8); *be++ = (bn );
964 xx = mp_to_unsigned_bin(ltc->rsa.N, be);
967 bn = mp_count_bits(ltc->rsa.e);
968 *be++ = (bn >> 8); *be++ = (bn );
970 xx = mp_to_unsigned_bin(ltc->rsa.e, be);
974 bn = mp_count_bits(ltc->dsa.p);
975 *be++ = (bn >> 8); *be++ = (bn );
977 xx = mp_to_unsigned_bin(ltc->dsa.p, be);
980 bn = mp_count_bits(ltc->dsa.q);
981 *be++ = (bn >> 8); *be++ = (bn );
983 xx = mp_to_unsigned_bin(ltc->dsa.q, be);
986 bn = mp_count_bits(ltc->dsa.g);
987 *be++ = (bn >> 8); *be++ = (bn );
989 xx = mp_to_unsigned_bin(ltc->dsa.g, be);
992 bn = mp_count_bits(ltc->dsa.y);
993 *be++ = (bn >> 8); *be++ = (bn );
995 xx = mp_to_unsigned_bin(ltc->dsa.y, be);
1003 switch (ltc->nbits) {
1004 case 192: s =
"2a8648ce3d030101";
break;
1005 case 224: s =
"2b81040021";
break;
1007 case 256: s =
"2a8648ce3d030107";
break;
1008 case 384: s =
"2b81040022";
break;
1010 case 521: s =
"2b81040023";
break;
1014 for (i = 0; i <
ns; i += 2)
1018 {
unsigned long nQ = (
sizeof(pkt) - (be+2 - pkt));
1019 xx = ecc_ansi_x963_export(<c->ecdsa, be+2, &nQ);
1020 assert(xx == CRYPT_OK);
1024 *be++ = (bn >> 8); *be++ = (bn );
1031 pktlen = (be - pkt);
1038 dig->pub = memcpy(
xmalloc(pktlen), pkt, pktlen);
1039 dig->publen = pktlen;
1052 time_t now =
time(NULL);
1062 *be++ = 0x80 | (sigp->tag << 2) | 0x01;
1066 *be++ = sigp->version = 0x04;
1068 *be++ = sigp->pubkey_algo = pubp->pubkey_algo;
1069 *be++ = sigp->hash_algo;
1077 *be++ = sigp->time[0] = (bt >> 24);
1078 *be++ = sigp->time[1] = (bt >> 16);
1079 *be++ = sigp->time[2] = (bt >> 8);
1080 *be++ = sigp->time[3] = (bt );
1084 bt = 30 * 24 * 60 * 60;
1085 *be++ = sigp->expire[0] = (bt >> 24);
1086 *be++ = sigp->expire[1] = (bt >> 16);
1087 *be++ = sigp->expire[2] = (bt >> 8);
1088 *be++ = sigp->expire[3] = (bt );
1102 sigp->hashlen = (be - h);
1103 h[-2] = (sigp->hashlen >> 8);
1104 h[-1] = (sigp->hashlen );
1107 if (sigp->hash != NULL)
1112 trailer[0] = sigp->version;
1114 trailer[2] = (sigp->hashlen >> 24);
1115 trailer[3] = (sigp->hashlen >> 16);
1116 trailer[4] = (sigp->hashlen >> 8);
1117 trailer[5] = (sigp->hashlen );
1121 sigp->signhash16[0] = 0x00;
1122 sigp->signhash16[1] = 0x00;
1123 switch (pubp->pubkey_algo) {
1137 h = (uint8_t *) ltc->digest;
1138 sigp->signhash16[0] = h[0];
1139 sigp->signhash16[1] = h[1];
1150 *be++ = pubp->signid[0];
1151 *be++ = pubp->signid[1];
1152 *be++ = pubp->signid[2];
1153 *be++ = pubp->signid[3];
1154 *be++ = pubp->signid[4];
1155 *be++ = pubp->signid[5];
1156 *be++ = pubp->signid[6];
1157 *be++ = pubp->signid[7];
1163 *be++ = sigp->signhash16[0];
1164 *be++ = sigp->signhash16[1];
1166 switch (pubp->pubkey_algo) {
1171 bn = mp_count_bits(ltc->c);
1175 xx = mp_to_unsigned_bin(ltc->c, be);
1179 bn = mp_count_bits(ltc->r);
1183 xx = mp_to_unsigned_bin(ltc->r, be);
1186 bn = mp_count_bits(ltc->s);
1190 xx = mp_to_unsigned_bin(ltc->s, be);
1194 bn = mp_count_bits(ltc->r);
1198 xx = mp_to_unsigned_bin(ltc->r, be);
1201 bn = mp_count_bits(ltc->s);
1205 xx = mp_to_unsigned_bin(ltc->s, be);
1210 pktlen = (be - pkt);
1215 dig->sig = memcpy(
xmalloc(pktlen), pkt, pktlen);
1216 dig->siglen = pktlen;
pgpDigParams pgpGetPubkey(pgpDig dig)
Return OpenPGP pubkey parameters.
char * xstrdup(const char *str)
struct pgpDigParams_s * pgpDigParams
pgpImplVecs_t rpmltcImplVecs
Implementation specific parameter storage.
static unsigned char nibble(char c)
Convert hex to binary nibble.
static int pgpImplSign(pgpDig dig)
const char * pgpPubkeyAlgo2Name(uint32_t algo)
int rpmltcExportPubkey(pgpDig dig)
static int pgpImplSetDSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Yet Another syslog(3) API clone.
void * xcalloc(size_t nmemb, size_t size)
int rpmDigestUpdate(DIGEST_CTX ctx, const void *data, size_t len)
Update context with next plain text buffer.
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
static unsigned int pgpMpiBits(const rpmuint8_t *p)
Return no.
pgpHashAlgo rpmDigestAlgo(DIGEST_CTX ctx)
Return digest algorithm identifier.
pgpDigParams pgpGetSignature(pgpDig dig)
Return OpenPGP signature parameters.
static int pgpImplSetECDSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
static int pgpImplSetRSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
static unsigned int pgpMpiLen(const rpmuint8_t *p)
Return no.
int pgpPubkeyFingerprint(const rpmuint8_t *pkt, size_t pktlen, rpmuint8_t *keyid)
Print/parse an OpenPGP subtype packet.
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
const char * pgpHashAlgo2Name(uint32_t algo)
int rpmDigestFinal(DIGEST_CTX ctx, void *datap, size_t *lenp, int asAscii)
Return digest and destroy context.
int rpmltcExportSignature(pgpDig dig, DIGEST_CTX ctx)
static char * pgpHexStr(const rpmuint8_t *p, size_t plen)
Return hex formatted representation of bytes.