comparison libtomcrypt/src/pk/dsa/dsa_sign_hash.c @ 1471:6dba84798cd5

Update to libtomcrypt 1.18.1, merged with Dropbear changes
author Matt Johnston <matt@ucc.asn.au>
date Fri, 09 Feb 2018 21:44:05 +0800
parents f849a5ca2efc
children
comparison
equal deleted inserted replaced
1470:8bba51a55704 1471:6dba84798cd5
3 * LibTomCrypt is a library that provides various cryptographic 3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner. 4 * algorithms in a highly modular and flexible manner.
5 * 5 *
6 * The library is free for all purposes without any express 6 * The library is free for all purposes without any express
7 * guarantee it works. 7 * guarantee it works.
8 *
9 * Tom St Denis, [email protected], http://libtom.org
10 */ 8 */
11 #include "tomcrypt.h" 9 #include "tomcrypt.h"
12 10
13 /** 11 /**
14 @file dsa_sign_hash.c 12 @file dsa_sign_hash.c
32 void *r, void *s, 30 void *r, void *s,
33 prng_state *prng, int wprng, dsa_key *key) 31 prng_state *prng, int wprng, dsa_key *key)
34 { 32 {
35 void *k, *kinv, *tmp; 33 void *k, *kinv, *tmp;
36 unsigned char *buf; 34 unsigned char *buf;
37 int err; 35 int err, qbits;
38 36
39 LTC_ARGCHK(in != NULL); 37 LTC_ARGCHK(in != NULL);
40 LTC_ARGCHK(r != NULL); 38 LTC_ARGCHK(r != NULL);
41 LTC_ARGCHK(s != NULL); 39 LTC_ARGCHK(s != NULL);
42 LTC_ARGCHK(key != NULL); 40 LTC_ARGCHK(key != NULL);
59 } 57 }
60 58
61 /* Init our temps */ 59 /* Init our temps */
62 if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK) { goto ERRBUF; } 60 if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK) { goto ERRBUF; }
63 61
62 qbits = mp_count_bits(key->q);
64 retry: 63 retry:
65 64
66 do { 65 do {
67 /* gen random k */ 66 /* gen random k */
68 if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) { 67 if ((err = rand_bn_bits(k, qbits, prng, wprng)) != CRYPT_OK) { goto error; }
69 err = CRYPT_ERROR_READPRNG;
70 goto error;
71 }
72 68
73 /* read k */ 69 /* k should be from range: 1 <= k <= q-1 (see FIPS 186-4 B.2.2) */
74 if ((err = mp_read_unsigned_bin(k, buf, key->qord)) != CRYPT_OK) { goto error; } 70 if (mp_cmp_d(k, 0) != LTC_MP_GT || mp_cmp(k, key->q) != LTC_MP_LT) { goto retry; }
75
76 /* k > 1 ? */
77 if (mp_cmp_d(k, 1) != LTC_MP_GT) { goto retry; }
78 71
79 /* test gcd */ 72 /* test gcd */
80 if ((err = mp_gcd(k, key->q, tmp)) != CRYPT_OK) { goto error; } 73 if ((err = mp_gcd(k, key->q, tmp)) != CRYPT_OK) { goto error; }
81 } while (mp_cmp_d(tmp, 1) != LTC_MP_EQ); 74 } while (mp_cmp_d(tmp, 1) != LTC_MP_EQ);
82 75
87 if ((err = mp_exptmod(key->g, k, key->p, r)) != CRYPT_OK) { goto error; } 80 if ((err = mp_exptmod(key->g, k, key->p, r)) != CRYPT_OK) { goto error; }
88 if ((err = mp_mod(r, key->q, r)) != CRYPT_OK) { goto error; } 81 if ((err = mp_mod(r, key->q, r)) != CRYPT_OK) { goto error; }
89 82
90 if (mp_iszero(r) == LTC_MP_YES) { goto retry; } 83 if (mp_iszero(r) == LTC_MP_YES) { goto retry; }
91 84
85 /* FIPS 186-4 4.6: use leftmost min(bitlen(q), bitlen(hash)) bits of 'hash'*/
86 inlen = MIN(inlen, (unsigned long)(key->qord));
87
92 /* now find s = (in + xr)/k mod q */ 88 /* now find s = (in + xr)/k mod q */
93 if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, inlen)) != CRYPT_OK) { goto error; } 89 if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, inlen)) != CRYPT_OK) { goto error; }
94 if ((err = mp_mul(key->x, r, s)) != CRYPT_OK) { goto error; } 90 if ((err = mp_mul(key->x, r, s)) != CRYPT_OK) { goto error; }
95 if ((err = mp_add(s, tmp, s)) != CRYPT_OK) { goto error; } 91 if ((err = mp_add(s, tmp, s)) != CRYPT_OK) { goto error; }
96 if ((err = mp_mulmod(s, kinv, key->q, s)) != CRYPT_OK) { goto error; } 92 if ((err = mp_mulmod(s, kinv, key->q, s)) != CRYPT_OK) { goto error; }
97 93
98 if (mp_iszero(s) == LTC_MP_YES) { goto retry; } 94 if (mp_iszero(s) == LTC_MP_YES) { goto retry; }
99 95
100 err = CRYPT_OK; 96 err = CRYPT_OK;
101 error: 97 error:
102 mp_clear_multi(k, kinv, tmp, NULL); 98 mp_clear_multi(k, kinv, tmp, NULL);
103 ERRBUF: 99 ERRBUF:
104 #ifdef LTC_CLEAN_STACK 100 #ifdef LTC_CLEAN_STACK
105 zeromem(buf, LTC_MDSA_MAX_GROUP); 101 zeromem(buf, LTC_MDSA_MAX_GROUP);
106 #endif 102 #endif
137 133
138 if ((err = dsa_sign_hash_raw(in, inlen, r, s, prng, wprng, key)) != CRYPT_OK) { 134 if ((err = dsa_sign_hash_raw(in, inlen, r, s, prng, wprng, key)) != CRYPT_OK) {
139 goto error; 135 goto error;
140 } 136 }
141 137
142 err = der_encode_sequence_multi(out, outlen, 138 err = der_encode_sequence_multi(out, outlen,
143 LTC_ASN1_INTEGER, 1UL, r, 139 LTC_ASN1_INTEGER, 1UL, r,
144 LTC_ASN1_INTEGER, 1UL, s, 140 LTC_ASN1_INTEGER, 1UL, s,
145 LTC_ASN1_EOL, 0UL, NULL); 141 LTC_ASN1_EOL, 0UL, NULL);
146 142
147 error: 143 error:
148 mp_clear_multi(r, s, NULL); 144 mp_clear_multi(r, s, NULL);
149 return err; 145 return err;
150 } 146 }
151 147
152 #endif 148 #endif
153 149
154 /* $Source$ */ 150 /* ref: $Format:%D$ */
155 /* $Revision$ */ 151 /* git commit: $Format:%H$ */
156 /* $Date$ */ 152 /* commit time: $Format:%ai$ */