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$ */