2 * Copyright (c) 2007, Cameron Rich
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 * * Neither the name of the axTLS project nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * Implements the RSA public encryption algorithm. Uses the bigint library to
33 * perform its calculations.
42 void RSA_priv_key_new(RSA_CTX
**ctx
,
43 const uint8_t *modulus
, int mod_len
,
44 const uint8_t *pub_exp
, int pub_len
,
45 const uint8_t *priv_exp
, int priv_len
47 , const uint8_t *p
, int p_len
,
48 const uint8_t *q
, int q_len
,
49 const uint8_t *dP
, int dP_len
,
50 const uint8_t *dQ
, int dQ_len
,
51 const uint8_t *qInv
, int qInv_len
57 RSA_pub_key_new(ctx
, modulus
, mod_len
, pub_exp
, pub_len
);
59 bi_ctx
= rsa_ctx
->bi_ctx
;
60 rsa_ctx
->d
= bi_import(bi_ctx
, priv_exp
, priv_len
);
61 bi_permanent(rsa_ctx
->d
);
63 #ifdef CONFIG_BIGINT_CRT
64 rsa_ctx
->p
= bi_import(bi_ctx
, p
, p_len
);
65 rsa_ctx
->q
= bi_import(bi_ctx
, q
, q_len
);
66 rsa_ctx
->dP
= bi_import(bi_ctx
, dP
, dP_len
);
67 rsa_ctx
->dQ
= bi_import(bi_ctx
, dQ
, dQ_len
);
68 rsa_ctx
->qInv
= bi_import(bi_ctx
, qInv
, qInv_len
);
69 bi_permanent(rsa_ctx
->dP
);
70 bi_permanent(rsa_ctx
->dQ
);
71 bi_permanent(rsa_ctx
->qInv
);
72 bi_set_mod(bi_ctx
, rsa_ctx
->p
, BIGINT_P_OFFSET
);
73 bi_set_mod(bi_ctx
, rsa_ctx
->q
, BIGINT_Q_OFFSET
);
77 void RSA_pub_key_new(RSA_CTX
**ctx
,
78 const uint8_t *modulus
, int mod_len
,
79 const uint8_t *pub_exp
, int pub_len
)
84 if (*ctx
) /* if we load multiple certs, dump the old one */
87 bi_ctx
= bi_initialize();
88 *ctx
= (RSA_CTX
*)calloc(1, sizeof(RSA_CTX
));
90 rsa_ctx
->bi_ctx
= bi_ctx
;
91 rsa_ctx
->num_octets
= (mod_len
& 0xFFF0);
92 rsa_ctx
->m
= bi_import(bi_ctx
, modulus
, mod_len
);
93 bi_set_mod(bi_ctx
, rsa_ctx
->m
, BIGINT_M_OFFSET
);
94 rsa_ctx
->e
= bi_import(bi_ctx
, pub_exp
, pub_len
);
95 bi_permanent(rsa_ctx
->e
);
99 * Free up any RSA context resources.
101 void RSA_free(RSA_CTX
*rsa_ctx
)
104 if (rsa_ctx
== NULL
) /* deal with ptrs that are null */
107 bi_ctx
= rsa_ctx
->bi_ctx
;
109 bi_depermanent(rsa_ctx
->e
);
110 bi_free(bi_ctx
, rsa_ctx
->e
);
111 bi_free_mod(rsa_ctx
->bi_ctx
, BIGINT_M_OFFSET
);
115 bi_depermanent(rsa_ctx
->d
);
116 bi_free(bi_ctx
, rsa_ctx
->d
);
117 #ifdef CONFIG_BIGINT_CRT
118 bi_depermanent(rsa_ctx
->dP
);
119 bi_depermanent(rsa_ctx
->dQ
);
120 bi_depermanent(rsa_ctx
->qInv
);
121 bi_free(bi_ctx
, rsa_ctx
->dP
);
122 bi_free(bi_ctx
, rsa_ctx
->dQ
);
123 bi_free(bi_ctx
, rsa_ctx
->qInv
);
124 bi_free_mod(rsa_ctx
->bi_ctx
, BIGINT_P_OFFSET
);
125 bi_free_mod(rsa_ctx
->bi_ctx
, BIGINT_Q_OFFSET
);
129 bi_terminate(bi_ctx
);
134 * @brief Use PKCS1.5 for decryption/verification.
135 * @param ctx [in] The context
136 * @param in_data [in] The data to encrypt (must be < modulus size-11)
137 * @param out_data [out] The encrypted data.
138 * @param is_decryption [in] Decryption or verify operation.
139 * @return The number of bytes that were originally encrypted. -1 on error.
140 * @see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
142 int RSA_decrypt(const RSA_CTX
*ctx
, const uint8_t *in_data
,
143 uint8_t *out_data
, int is_decryption
)
145 const int byte_size
= ctx
->num_octets
;
147 bigint
*decrypted_bi
, *dat_bi
;
148 uint8_t *block
= (uint8_t *)alloca(byte_size
);
150 memset(out_data
, 0, byte_size
); /* initialise */
153 dat_bi
= bi_import(ctx
->bi_ctx
, in_data
, byte_size
);
154 #ifdef CONFIG_SSL_CERT_VERIFICATION
155 decrypted_bi
= is_decryption
? /* decrypt or verify? */
156 RSA_private(ctx
, dat_bi
) : RSA_public(ctx
, dat_bi
);
157 #else /* always a decryption */
158 decrypted_bi
= RSA_private(ctx
, dat_bi
);
161 /* convert to a normal block */
162 bi_export(ctx
->bi_ctx
, decrypted_bi
, block
, byte_size
);
164 i
= 10; /* start at the first possible non-padded byte */
166 #ifdef CONFIG_SSL_CERT_VERIFICATION
167 if (is_decryption
== 0) /* PKCS1.5 signing pads with "0xff"s */
169 while (block
[i
++] == 0xff && i
< byte_size
);
171 if (block
[i
-2] != 0xff)
172 i
= byte_size
; /*ensure size is 0 */
174 else /* PKCS1.5 encryption padding is random */
177 while (block
[i
++] && i
< byte_size
);
179 size
= byte_size
- i
;
181 /* get only the bit we want */
183 memcpy(out_data
, &block
[i
], size
);
185 return size
? size
: -1;
189 * Performs m = c^d mod n
191 bigint
*RSA_private(const RSA_CTX
*c
, bigint
*bi_msg
)
193 #ifdef CONFIG_BIGINT_CRT
194 return bi_crt(c
->bi_ctx
, bi_msg
, c
->dP
, c
->dQ
, c
->p
, c
->q
, c
->qInv
);
196 BI_CTX
*ctx
= c
->bi_ctx
;
197 ctx
->mod_offset
= BIGINT_M_OFFSET
;
198 return bi_mod_power(ctx
, bi_msg
, c
->d
);
202 #ifdef CONFIG_SSL_FULL_MODE
204 * Used for diagnostics.
206 void RSA_print(const RSA_CTX
*rsa_ctx
)
211 printf("----------------- RSA DEBUG ----------------\n");
212 printf("Size:\t%d\n", rsa_ctx
->num_octets
);
213 bi_print("Modulus", rsa_ctx
->m
);
214 bi_print("Public Key", rsa_ctx
->e
);
215 bi_print("Private Key", rsa_ctx
->d
);
219 #if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT)
221 * Performs c = m^e mod n
223 bigint
*RSA_public(const RSA_CTX
* c
, bigint
*bi_msg
)
225 c
->bi_ctx
->mod_offset
= BIGINT_M_OFFSET
;
226 return bi_mod_power(c
->bi_ctx
, bi_msg
, c
->e
);
230 * Use PKCS1.5 for encryption/signing.
231 * see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
233 int RSA_encrypt(const RSA_CTX
*ctx
, const uint8_t *in_data
, uint16_t in_len
,
234 uint8_t *out_data
, int is_signing
)
236 int byte_size
= ctx
->num_octets
;
237 int num_pads_needed
= byte_size
-in_len
-3;
238 bigint
*dat_bi
, *encrypt_bi
;
240 /* note: in_len+11 must be > byte_size */
241 out_data
[0] = 0; /* ensure encryption block is < modulus */
245 out_data
[1] = 1; /* PKCS1.5 signing pads with "0xff"'s */
246 memset(&out_data
[2], 0xff, num_pads_needed
);
248 else /* randomize the encryption padding with non-zero bytes */
251 get_random_NZ(num_pads_needed
, &out_data
[2]);
254 out_data
[2+num_pads_needed
] = 0;
255 memcpy(&out_data
[3+num_pads_needed
], in_data
, in_len
);
258 dat_bi
= bi_import(ctx
->bi_ctx
, out_data
, byte_size
);
259 encrypt_bi
= is_signing
? RSA_private(ctx
, dat_bi
) :
260 RSA_public(ctx
, dat_bi
);
261 bi_export(ctx
->bi_ctx
, encrypt_bi
, out_data
, byte_size
);
263 /* save a few bytes of memory */
264 bi_clear_cache(ctx
->bi_ctx
);
268 #endif /* CONFIG_SSL_CERT_VERIFICATION */