2 * Copyright(C) 2006 Cameron Rich
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Implements the RSA public encryption algorithm. Uses the bigint library to
21 * perform its calculations.
30 #ifdef CONFIG_BIGINT_CRT
31 static bigint
*bi_crt(const RSA_CTX
*rsa
, bigint
*bi
);
34 void RSA_priv_key_new(RSA_CTX
**ctx
,
35 const uint8_t *modulus
, int mod_len
,
36 const uint8_t *pub_exp
, int pub_len
,
37 const uint8_t *priv_exp
, int priv_len
39 , const uint8_t *p
, int p_len
,
40 const uint8_t *q
, int q_len
,
41 const uint8_t *dP
, int dP_len
,
42 const uint8_t *dQ
, int dQ_len
,
43 const uint8_t *qInv
, int qInv_len
49 RSA_pub_key_new(ctx
, modulus
, mod_len
, pub_exp
, pub_len
);
51 bi_ctx
= rsa_ctx
->bi_ctx
;
52 rsa_ctx
->d
= bi_import(bi_ctx
, priv_exp
, priv_len
);
53 bi_permanent(rsa_ctx
->d
);
55 #ifdef CONFIG_BIGINT_CRT
56 rsa_ctx
->p
= bi_import(bi_ctx
, p
, p_len
);
57 rsa_ctx
->q
= bi_import(bi_ctx
, q
, q_len
);
58 rsa_ctx
->dP
= bi_import(bi_ctx
, dP
, dP_len
);
59 rsa_ctx
->dQ
= bi_import(bi_ctx
, dQ
, dQ_len
);
60 rsa_ctx
->qInv
= bi_import(bi_ctx
, qInv
, qInv_len
);
61 bi_permanent(rsa_ctx
->dP
);
62 bi_permanent(rsa_ctx
->dQ
);
63 bi_permanent(rsa_ctx
->qInv
);
64 bi_set_mod(bi_ctx
, rsa_ctx
->p
, BIGINT_P_OFFSET
);
65 bi_set_mod(bi_ctx
, rsa_ctx
->q
, BIGINT_Q_OFFSET
);
69 void RSA_pub_key_new(RSA_CTX
**ctx
,
70 const uint8_t *modulus
, int mod_len
,
71 const uint8_t *pub_exp
, int pub_len
)
74 BI_CTX
*bi_ctx
= bi_initialize();
75 *ctx
= (RSA_CTX
*)calloc(1, sizeof(RSA_CTX
));
77 rsa_ctx
->bi_ctx
= bi_ctx
;
78 rsa_ctx
->num_octets
= (mod_len
& 0xFFF0);
79 rsa_ctx
->m
= bi_import(bi_ctx
, modulus
, mod_len
);
80 bi_set_mod(bi_ctx
, rsa_ctx
->m
, BIGINT_M_OFFSET
);
81 rsa_ctx
->e
= bi_import(bi_ctx
, pub_exp
, pub_len
);
82 bi_permanent(rsa_ctx
->e
);
86 * Free up any RSA context resources.
88 void RSA_free(RSA_CTX
*rsa_ctx
)
91 if (rsa_ctx
== NULL
) /* deal with ptrs that are null */
94 bi_ctx
= rsa_ctx
->bi_ctx
;
96 bi_depermanent(rsa_ctx
->e
);
97 bi_free(bi_ctx
, rsa_ctx
->e
);
98 bi_free_mod(rsa_ctx
->bi_ctx
, BIGINT_M_OFFSET
);
102 bi_depermanent(rsa_ctx
->d
);
103 bi_free(bi_ctx
, rsa_ctx
->d
);
104 #ifdef CONFIG_BIGINT_CRT
105 bi_depermanent(rsa_ctx
->dP
);
106 bi_depermanent(rsa_ctx
->dQ
);
107 bi_depermanent(rsa_ctx
->qInv
);
108 bi_free(bi_ctx
, rsa_ctx
->dP
);
109 bi_free(bi_ctx
, rsa_ctx
->dQ
);
110 bi_free(bi_ctx
, rsa_ctx
->qInv
);
111 bi_free_mod(rsa_ctx
->bi_ctx
, BIGINT_P_OFFSET
);
112 bi_free_mod(rsa_ctx
->bi_ctx
, BIGINT_Q_OFFSET
);
116 bi_terminate(bi_ctx
);
121 * @brief Use PKCS1.5 for decryption/verification.
122 * @param ctx [in] The context
123 * @param in_data [in] The data to encrypt (must be < modulus size-11)
124 * @param out_data [out] The encrypted data.
125 * @param is_decryption [in] Decryption or verify operation.
126 * @return The number of bytes that were originally encrypted. -1 on error.
127 * @see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
129 int RSA_decrypt(const RSA_CTX
*ctx
, const uint8_t *in_data
,
130 uint8_t *out_data
, int is_decryption
)
132 int byte_size
= ctx
->num_octets
;
135 bigint
*decrypted_bi
, *dat_bi
;
137 memset(out_data
, 0, byte_size
); /* initialise */
140 dat_bi
= bi_import(ctx
->bi_ctx
, in_data
, byte_size
);
141 #ifdef CONFIG_SSL_CERT_VERIFICATION
142 decrypted_bi
= is_decryption
? /* decrypt or verify? */
143 RSA_private(ctx
, dat_bi
) : RSA_public(ctx
, dat_bi
);
144 #else /* always a decryption */
145 decrypted_bi
= RSA_private(ctx
, dat_bi
);
148 /* convert to a normal block */
149 block
= (uint8_t *)malloc(byte_size
);
150 bi_export(ctx
->bi_ctx
, decrypted_bi
, block
, byte_size
);
152 i
= 10; /* start at the first possible non-padded byte */
154 #ifdef CONFIG_SSL_CERT_VERIFICATION
155 if (is_decryption
== 0) /* PKCS1.5 signing pads with "0xff"s */
157 while (block
[i
++] == 0xff && i
< byte_size
);
159 if (block
[i
-2] != 0xff)
160 i
= byte_size
; /*ensure size is 0 */
162 else /* PKCS1.5 encryption padding is random */
165 while (block
[i
++] && i
< byte_size
);
167 size
= byte_size
- i
;
169 /* get only the bit we want */
171 memcpy(out_data
, &block
[i
], size
);
174 return size
? size
: -1;
178 * Performs m = c^d mod n
180 bigint
*RSA_private(const RSA_CTX
*c
, bigint
*bi_msg
)
182 #ifdef CONFIG_BIGINT_CRT
183 return bi_crt(c
, bi_msg
);
185 BI_CTX
*ctx
= c
->bi_ctx
;
186 ctx
->mod_offset
= BIGINT_M_OFFSET
;
187 return bi_mod_power(ctx
, bi_msg
, c
->d
);
191 #ifdef CONFIG_BIGINT_CRT
193 * Use the Chinese Remainder Theorem to quickly perform RSA decrypts.
194 * This should really be in bigint.c (and was at one stage), but needs
195 * access to the RSA_CTX context...
197 static bigint
*bi_crt(const RSA_CTX
*rsa
, bigint
*bi
)
199 BI_CTX
*ctx
= rsa
->bi_ctx
;
202 /* Montgomery has a condition the 0 < x, y < m and these products violate
203 * that condition. So disable Montgomery when using CRT */
204 #if defined(CONFIG_BIGINT_MONTGOMERY)
205 ctx
->use_classical
= 1;
207 ctx
->mod_offset
= BIGINT_P_OFFSET
;
208 m1
= bi_mod_power(ctx
, bi_copy(bi
), rsa
->dP
);
210 ctx
->mod_offset
= BIGINT_Q_OFFSET
;
211 m2
= bi_mod_power(ctx
, bi
, rsa
->dQ
);
213 h
= bi_subtract(ctx
, bi_add(ctx
, m1
, rsa
->p
), bi_copy(m2
), NULL
);
214 h
= bi_multiply(ctx
, h
, rsa
->qInv
);
215 ctx
->mod_offset
= BIGINT_P_OFFSET
;
216 h
= bi_residue(ctx
, h
);
217 #if defined(CONFIG_BIGINT_MONTGOMERY)
218 ctx
->use_classical
= 0; /* reset for any further operation */
220 return bi_add(ctx
, m2
, bi_multiply(ctx
, rsa
->q
, h
));
224 #ifdef CONFIG_SSL_FULL_MODE
226 * Used for diagnostics.
228 void RSA_print(const RSA_CTX
*rsa_ctx
)
233 printf("----------------- RSA DEBUG ----------------\n");
234 printf("Size:\t%d\n", rsa_ctx
->num_octets
);
235 bi_print("Modulus", rsa_ctx
->m
);
236 bi_print("Public Key", rsa_ctx
->e
);
237 bi_print("Private Key", rsa_ctx
->d
);
241 #ifdef CONFIG_SSL_CERT_VERIFICATION
243 * Performs c = m^e mod n
245 bigint
*RSA_public(const RSA_CTX
* c
, bigint
*bi_msg
)
247 c
->bi_ctx
->mod_offset
= BIGINT_M_OFFSET
;
248 return bi_mod_power(c
->bi_ctx
, bi_msg
, c
->e
);
252 * Use PKCS1.5 for encryption/signing.
253 * see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
255 int RSA_encrypt(const RSA_CTX
*ctx
, const uint8_t *in_data
, uint16_t in_len
,
256 uint8_t *out_data
, int is_signing
)
258 int byte_size
= ctx
->num_octets
;
259 int num_pads_needed
= byte_size
-in_len
-3;
260 bigint
*dat_bi
, *encrypt_bi
;
262 /* note: in_len+11 must be > byte_size */
263 out_data
[0] = 0; /* ensure encryption block is < modulus */
267 out_data
[1] = 1; /* PKCS1.5 signing pads with "0xff"'s */
268 memset(&out_data
[2], 0xff, num_pads_needed
);
270 else /* randomize the encryption padding with non-zero bytes */
273 get_random_NZ(num_pads_needed
, &out_data
[2]);
276 out_data
[2+num_pads_needed
] = 0;
277 memcpy(&out_data
[3+num_pads_needed
], in_data
, in_len
);
280 dat_bi
= bi_import(ctx
->bi_ctx
, out_data
, byte_size
);
281 encrypt_bi
= is_signing
? RSA_private(ctx
, dat_bi
) :
282 RSA_public(ctx
, dat_bi
);
283 bi_export(ctx
->bi_ctx
, encrypt_bi
, out_data
, byte_size
);
289 * Take a signature and decrypt it.
291 bigint
*RSA_sign_verify(BI_CTX
*ctx
, const uint8_t *sig
, int sig_len
,
292 bigint
*modulus
, bigint
*pub_exp
)
296 bigint
*decrypted_bi
, *dat_bi
;
299 block
= (uint8_t *)malloc(sig_len
);
302 dat_bi
= bi_import(ctx
, sig
, sig_len
);
303 ctx
->mod_offset
= BIGINT_M_OFFSET
;
305 /* convert to a normal block */
306 decrypted_bi
= bi_mod_power2(ctx
, dat_bi
, modulus
, pub_exp
);
308 bi_export(ctx
, decrypted_bi
, block
, sig_len
);
309 ctx
->mod_offset
= BIGINT_M_OFFSET
;
311 i
= 10; /* start at the first possible non-padded byte */
312 while (block
[i
++] && i
< sig_len
);
315 /* get only the bit we want */
319 const uint8_t *sig_ptr
= x509_get_signature(&block
[i
], &len
);
323 bir
= bi_import(ctx
, sig_ptr
, len
);
332 #endif /* CONFIG_SSL_CERT_VERIFICATION */