99
1010#ifdef LTC_MRSA
1111
12- /**
13- Create an RSA key
14- @param prng An active PRNG state
15- @param wprng The index of the PRNG desired
16- @param size The size of the modulus (key size) desired (octets)
17- @param e The "e" value (public key). e==65537 is a good choice
18- @param key [out] Destination of a newly created private key pair
19- @return CRYPT_OK if successful, upon error all allocated ram is freed
20- */
21- int rsa_make_key (prng_state * prng , int wprng , int size , long e , rsa_key * key )
12+ static int s_rsa_make_key (prng_state * prng , int wprng , int size , void * e , rsa_key * key )
2213{
23- void * p , * q , * tmp1 , * tmp2 , * tmp3 ;
14+ void * p , * q , * tmp1 , * tmp2 ;
2415 int err ;
2516
2617 LTC_ARGCHK (ltc_mp .name != NULL );
2718 LTC_ARGCHK (key != NULL );
2819 LTC_ARGCHK (size > 0 );
2920
30- if ((e < 3 ) || ((e & 1 ) == 0 )) {
31- return CRYPT_INVALID_ARG ;
32- }
33-
3421 if ((err = prng_is_valid (wprng )) != CRYPT_OK ) {
3522 return err ;
3623 }
3724
38- if ((err = mp_init_multi (& p , & q , & tmp1 , & tmp2 , & tmp3 , NULL )) != CRYPT_OK ) {
25+ if ((err = mp_init_multi (& p , & q , & tmp1 , & tmp2 , NULL )) != CRYPT_OK ) {
3926 return err ;
4027 }
4128
4229 /* make primes p and q (optimization provided by Wayne Scott) */
43- if ((err = mp_set_int (tmp3 , e )) != CRYPT_OK ) { goto cleanup ; } /* tmp3 = e */
4430
4531 /* make prime "p" */
4632 do {
4733 if ((err = rand_prime ( p , size /2 , prng , wprng )) != CRYPT_OK ) { goto cleanup ; }
4834 if ((err = mp_sub_d ( p , 1 , tmp1 )) != CRYPT_OK ) { goto cleanup ; } /* tmp1 = p-1 */
49- if ((err = mp_gcd ( tmp1 , tmp3 , tmp2 )) != CRYPT_OK ) { goto cleanup ; } /* tmp2 = gcd(p-1, e) */
35+ if ((err = mp_gcd ( tmp1 , e , tmp2 )) != CRYPT_OK ) { goto cleanup ; } /* tmp2 = gcd(p-1, e) */
5036 } while (mp_cmp_d ( tmp2 , 1 ) != 0 ); /* while e divides p-1 */
5137
5238 /* make prime "q" */
5339 do {
5440 if ((err = rand_prime ( q , size /2 , prng , wprng )) != CRYPT_OK ) { goto cleanup ; }
5541 if ((err = mp_sub_d ( q , 1 , tmp1 )) != CRYPT_OK ) { goto cleanup ; } /* tmp1 = q-1 */
56- if ((err = mp_gcd ( tmp1 , tmp3 , tmp2 )) != CRYPT_OK ) { goto cleanup ; } /* tmp2 = gcd(q-1, e) */
42+ if ((err = mp_gcd ( tmp1 , e , tmp2 )) != CRYPT_OK ) { goto cleanup ; } /* tmp2 = gcd(q-1, e) */
5743 } while (mp_cmp_d ( tmp2 , 1 ) != 0 ); /* while e divides q-1 */
5844
5945 /* tmp1 = lcm(p-1, q-1) */
@@ -66,7 +52,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
6652 goto errkey ;
6753 }
6854
69- if ((err = mp_set_int ( key -> e , e )) != CRYPT_OK ) { goto errkey ; } /* key->e = e */
55+ if ((err = mp_copy ( e , key -> e )) != CRYPT_OK ) { goto errkey ; } /* key->e = e */
7056 if ((err = mp_invmod ( key -> e , tmp1 , key -> d )) != CRYPT_OK ) { goto errkey ; } /* key->d = 1/e mod lcm(p-1,q-1) */
7157 if ((err = mp_mul ( p , q , key -> N )) != CRYPT_OK ) { goto errkey ; } /* key->N = pq */
7258
@@ -90,7 +76,89 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
9076errkey :
9177 rsa_free (key );
9278cleanup :
93- mp_clear_multi (tmp3 , tmp2 , tmp1 , q , p , NULL );
79+ mp_clear_multi (tmp2 , tmp1 , q , p , NULL );
80+ return err ;
81+ }
82+
83+ /**
84+ Create an RSA key based on a long public exponent type
85+ @param prng An active PRNG state
86+ @param wprng The index of the PRNG desired
87+ @param size The size of the modulus (key size) desired (octets)
88+ @param e The "e" value (public key). e==65537 is a good choice
89+ @param key [out] Destination of a newly created private key pair
90+ @return CRYPT_OK if successful, upon error all allocated ram is freed
91+ */
92+ int rsa_make_key (prng_state * prng , int wprng , int size , long e , rsa_key * key )
93+ {
94+ void * tmp_e ;
95+ int err ;
96+
97+ if ((e < 3 ) || ((e & 1 ) == 0 )) {
98+ return CRYPT_INVALID_ARG ;
99+ }
100+
101+ if ((err = mp_init (& tmp_e )) != CRYPT_OK ) {
102+ return err ;
103+ }
104+
105+ if ((err = mp_set_int (tmp_e , e )) == CRYPT_OK )
106+ err = s_rsa_make_key (prng , wprng , size , tmp_e , key );
107+
108+ mp_clear (tmp_e );
109+
110+ return err ;
111+ }
112+
113+ /**
114+ Create an RSA key based on a hexadecimal public exponent type
115+ @param prng An active PRNG state
116+ @param wprng The index of the PRNG desired
117+ @param size The size of the modulus (key size) desired (octets)
118+ @param e The "e" value (public key). e==65537 is a good choice
119+ @param elen The length of e (octets)
120+ @param key [out] Destination of a newly created private key pair
121+ @return CRYPT_OK if successful, upon error all allocated ram is freed
122+ */
123+ int rsa_make_key_ubin_e (prng_state * prng , int wprng , int size ,
124+ const unsigned char * e , unsigned long elen , rsa_key * key )
125+ {
126+ int err ;
127+ void * tmp_e ;
128+
129+ if ((err = mp_init (& tmp_e )) != CRYPT_OK ) {
130+ return err ;
131+ }
132+
133+ if ((err = mp_read_unsigned_bin (tmp_e , (unsigned char * )e , elen )) == CRYPT_OK )
134+ err = rsa_make_key_bn_e (prng , wprng , size , tmp_e , key );
135+
136+ mp_clear (tmp_e );
137+
138+ return err ;
139+ }
140+
141+ /**
142+ Create an RSA key based on a bignumber public exponent type
143+ @param prng An active PRNG state
144+ @param wprng The index of the PRNG desired
145+ @param size The size of the modulus (key size) desired (octets)
146+ @param e The "e" value (public key). e==65537 is a good choice
147+ @param key [out] Destination of a newly created private key pair
148+ @return CRYPT_OK if successful, upon error all allocated ram is freed
149+ */
150+ int rsa_make_key_bn_e (prng_state * prng , int wprng , int size , void * e , rsa_key * key )
151+ {
152+ int err ;
153+ int e_bits ;
154+
155+ e_bits = mp_count_bits (e );
156+ if ((e_bits > 1 && e_bits < 256 ) && (mp_get_digit (e , 0 ) & 1 )) {
157+ err = s_rsa_make_key (prng , wprng , size , e , key );
158+ } else {
159+ err = CRYPT_INVALID_ARG ;
160+ }
161+
94162 return err ;
95163}
96164
0 commit comments