Mercurial > dropbear
comparison libtomcrypt/src/pk/rsa/rsa_exptmod.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 rsa_exptmod.c | 12 @file rsa_exptmod.c |
15 RSA LTC_PKCS exptmod, Tom St Denis | 13 RSA PKCS exptmod, Tom St Denis |
16 */ | 14 Added RSA blinding --nmav |
15 */ | |
17 | 16 |
18 #ifdef LTC_MRSA | 17 #ifdef LTC_MRSA |
19 | 18 |
20 /** | 19 /** |
21 Compute an RSA modular exponentiation | 20 Compute an RSA modular exponentiation |
22 @param in The input data to send into RSA | 21 @param in The input data to send into RSA |
23 @param inlen The length of the input (octets) | 22 @param inlen The length of the input (octets) |
24 @param out [out] The destination | 23 @param out [out] The destination |
25 @param outlen [in/out] The max size and resulting size of the output | 24 @param outlen [in/out] The max size and resulting size of the output |
26 @param which Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC | 25 @param which Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC |
27 @param key The RSA key to use | 26 @param key The RSA key to use |
28 @return CRYPT_OK if successful | 27 @return CRYPT_OK if successful |
29 */ | 28 */ |
30 int rsa_exptmod(const unsigned char *in, unsigned long inlen, | 29 int rsa_exptmod(const unsigned char *in, unsigned long inlen, |
31 unsigned char *out, unsigned long *outlen, int which, | 30 unsigned char *out, unsigned long *outlen, int which, |
32 rsa_key *key) | 31 rsa_key *key) |
33 { | 32 { |
34 void *tmp, *tmpa, *tmpb; | 33 void *tmp, *tmpa, *tmpb; |
34 #ifdef LTC_RSA_BLINDING | |
35 void *rnd, *rndi /* inverse of rnd */; | |
36 #endif | |
35 unsigned long x; | 37 unsigned long x; |
36 int err; | 38 int err, has_crt_parameters; |
37 | 39 |
38 LTC_ARGCHK(in != NULL); | 40 LTC_ARGCHK(in != NULL); |
39 LTC_ARGCHK(out != NULL); | 41 LTC_ARGCHK(out != NULL); |
40 LTC_ARGCHK(outlen != NULL); | 42 LTC_ARGCHK(outlen != NULL); |
41 LTC_ARGCHK(key != NULL); | 43 LTC_ARGCHK(key != NULL); |
42 | 44 |
43 /* is the key of the right type for the operation? */ | 45 /* is the key of the right type for the operation? */ |
44 if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) { | 46 if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) { |
45 return CRYPT_PK_NOT_PRIVATE; | 47 return CRYPT_PK_NOT_PRIVATE; |
46 } | 48 } |
47 | 49 |
49 if (which != PK_PRIVATE && which != PK_PUBLIC) { | 51 if (which != PK_PRIVATE && which != PK_PUBLIC) { |
50 return CRYPT_PK_INVALID_TYPE; | 52 return CRYPT_PK_INVALID_TYPE; |
51 } | 53 } |
52 | 54 |
53 /* init and copy into tmp */ | 55 /* init and copy into tmp */ |
54 if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK) { return err; } | 56 if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, |
55 if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; } | 57 #ifdef LTC_RSA_BLINDING |
58 &rnd, &rndi, | |
59 #endif /* LTC_RSA_BLINDING */ | |
60 NULL)) != CRYPT_OK) | |
61 { return err; } | |
62 if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) | |
63 { goto error; } | |
64 | |
56 | 65 |
57 /* sanity check on the input */ | 66 /* sanity check on the input */ |
58 if (mp_cmp(key->N, tmp) == LTC_MP_LT) { | 67 if (mp_cmp(key->N, tmp) == LTC_MP_LT) { |
59 err = CRYPT_PK_INVALID_SIZE; | 68 err = CRYPT_PK_INVALID_SIZE; |
60 goto error; | 69 goto error; |
61 } | 70 } |
62 | 71 |
63 /* are we using the private exponent and is the key optimized? */ | 72 /* are we using the private exponent and is the key optimized? */ |
64 if (which == PK_PRIVATE) { | 73 if (which == PK_PRIVATE) { |
65 /* tmpa = tmp^dP mod p */ | 74 #ifdef LTC_RSA_BLINDING |
66 if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; } | 75 /* do blinding */ |
76 err = mp_rand(rnd, mp_get_digit_count(key->N)); | |
77 if (err != CRYPT_OK) { | |
78 goto error; | |
79 } | |
67 | 80 |
68 /* tmpb = tmp^dQ mod q */ | 81 /* rndi = 1/rnd mod N */ |
69 if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error; } | 82 err = mp_invmod(rnd, key->N, rndi); |
83 if (err != CRYPT_OK) { | |
84 goto error; | |
85 } | |
70 | 86 |
71 /* tmp = (tmpa - tmpb) * qInv (mod p) */ | 87 /* rnd = rnd^e */ |
72 if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error; } | 88 err = mp_exptmod( rnd, key->e, key->N, rnd); |
73 if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error; } | 89 if (err != CRYPT_OK) { |
90 goto error; | |
91 } | |
74 | 92 |
75 /* tmp = tmpb + q * tmp */ | 93 /* tmp = tmp*rnd mod N */ |
76 if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; } | 94 err = mp_mulmod( tmp, rnd, key->N, tmp); |
77 if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; } | 95 if (err != CRYPT_OK) { |
96 goto error; | |
97 } | |
98 #endif /* LTC_RSA_BLINDING */ | |
99 | |
100 has_crt_parameters = (key->p != NULL) && (mp_get_digit_count(key->p) != 0) && | |
101 (key->q != NULL) && (mp_get_digit_count(key->q) != 0) && | |
102 (key->dP != NULL) && (mp_get_digit_count(key->dP) != 0) && | |
103 (key->dQ != NULL) && (mp_get_digit_count(key->dQ) != 0) && | |
104 (key->qP != NULL) && (mp_get_digit_count(key->qP) != 0); | |
105 | |
106 if (!has_crt_parameters) { | |
107 /* | |
108 * In case CRT optimization parameters are not provided, | |
109 * the private key is directly used to exptmod it | |
110 */ | |
111 if ((err = mp_exptmod(tmp, key->d, key->N, tmp)) != CRYPT_OK) { goto error; } | |
112 } else { | |
113 /* tmpa = tmp^dP mod p */ | |
114 if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; } | |
115 | |
116 /* tmpb = tmp^dQ mod q */ | |
117 if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error; } | |
118 | |
119 /* tmp = (tmpa - tmpb) * qInv (mod p) */ | |
120 if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error; } | |
121 if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error; } | |
122 | |
123 /* tmp = tmpb + q * tmp */ | |
124 if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; } | |
125 if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; } | |
126 } | |
127 | |
128 #ifdef LTC_RSA_BLINDING | |
129 /* unblind */ | |
130 err = mp_mulmod( tmp, rndi, key->N, tmp); | |
131 if (err != CRYPT_OK) { | |
132 goto error; | |
133 } | |
134 #endif | |
135 | |
136 #ifdef LTC_RSA_CRT_HARDENING | |
137 if (has_crt_parameters) { | |
138 if ((err = mp_exptmod(tmp, key->e, key->N, tmpa)) != CRYPT_OK) { goto error; } | |
139 if ((err = mp_read_unsigned_bin(tmpb, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; } | |
140 if (mp_cmp(tmpa, tmpb) != LTC_MP_EQ) { err = CRYPT_ERROR; goto error; } | |
141 } | |
142 #endif | |
78 } else { | 143 } else { |
79 /* exptmod it */ | 144 /* exptmod it */ |
80 if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK) { goto error; } | 145 if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK) { goto error; } |
81 } | 146 } |
82 | 147 |
100 if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK) { goto error; } | 165 if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK) { goto error; } |
101 | 166 |
102 /* clean up and return */ | 167 /* clean up and return */ |
103 err = CRYPT_OK; | 168 err = CRYPT_OK; |
104 error: | 169 error: |
105 mp_clear_multi(tmp, tmpa, tmpb, NULL); | 170 mp_clear_multi( |
171 #ifdef LTC_RSA_BLINDING | |
172 rndi, rnd, | |
173 #endif /* LTC_RSA_BLINDING */ | |
174 tmpb, tmpa, tmp, NULL); | |
106 return err; | 175 return err; |
107 } | 176 } |
108 | 177 |
109 #endif | 178 #endif |
110 | 179 |
111 /* $Source$ */ | 180 /* ref: $Format:%D$ */ |
112 /* $Revision$ */ | 181 /* git commit: $Format:%H$ */ |
113 /* $Date$ */ | 182 /* commit time: $Format:%ai$ */ |