]>
git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/net/https/axTLS/crypto/rsa.c
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.
43 void RSA_priv_key_new(RSA_CTX
**ctx
,
44 const uint8_t *modulus
, int mod_len
,
45 const uint8_t *pub_exp
, int pub_len
,
46 const uint8_t *priv_exp
, int priv_len
48 , const uint8_t *p
, int p_len
,
49 const uint8_t *q
, int q_len
,
50 const uint8_t *dP
, int dP_len
,
51 const uint8_t *dQ
, int dQ_len
,
52 const uint8_t *qInv
, int qInv_len
58 RSA_pub_key_new(ctx
, modulus
, mod_len
, pub_exp
, pub_len
);
60 bi_ctx
= rsa_ctx
->bi_ctx
;
61 rsa_ctx
->d
= bi_import(bi_ctx
, priv_exp
, priv_len
);
62 bi_permanent(rsa_ctx
->d
);
64 #ifdef CONFIG_BIGINT_CRT
65 rsa_ctx
->p
= bi_import(bi_ctx
, p
, p_len
);
66 rsa_ctx
->q
= bi_import(bi_ctx
, q
, q_len
);
67 rsa_ctx
->dP
= bi_import(bi_ctx
, dP
, dP_len
);
68 rsa_ctx
->dQ
= bi_import(bi_ctx
, dQ
, dQ_len
);
69 rsa_ctx
->qInv
= bi_import(bi_ctx
, qInv
, qInv_len
);
70 bi_permanent(rsa_ctx
->dP
);
71 bi_permanent(rsa_ctx
->dQ
);
72 bi_permanent(rsa_ctx
->qInv
);
73 bi_set_mod(bi_ctx
, rsa_ctx
->p
, BIGINT_P_OFFSET
);
74 bi_set_mod(bi_ctx
, rsa_ctx
->q
, BIGINT_Q_OFFSET
);
78 void RSA_pub_key_new(RSA_CTX
**ctx
,
79 const uint8_t *modulus
, int mod_len
,
80 const uint8_t *pub_exp
, int pub_len
)
85 if (*ctx
) /* if we load multiple certs, dump the old one */
88 bi_ctx
= bi_initialize();
89 *ctx
= (RSA_CTX
*)calloc(1, sizeof(RSA_CTX
));
91 rsa_ctx
->bi_ctx
= bi_ctx
;
92 rsa_ctx
->num_octets
= mod_len
;
93 rsa_ctx
->m
= bi_import(bi_ctx
, modulus
, mod_len
);
94 bi_set_mod(bi_ctx
, rsa_ctx
->m
, BIGINT_M_OFFSET
);
95 rsa_ctx
->e
= bi_import(bi_ctx
, pub_exp
, pub_len
);
96 bi_permanent(rsa_ctx
->e
);
100 * Free up any RSA context resources.
102 void RSA_free(RSA_CTX
*rsa_ctx
)
105 if (rsa_ctx
== NULL
) /* deal with ptrs that are null */
108 bi_ctx
= rsa_ctx
->bi_ctx
;
110 bi_depermanent(rsa_ctx
->e
);
111 bi_free(bi_ctx
, rsa_ctx
->e
);
112 bi_free_mod(rsa_ctx
->bi_ctx
, BIGINT_M_OFFSET
);
116 bi_depermanent(rsa_ctx
->d
);
117 bi_free(bi_ctx
, rsa_ctx
->d
);
118 #ifdef CONFIG_BIGINT_CRT
119 bi_depermanent(rsa_ctx
->dP
);
120 bi_depermanent(rsa_ctx
->dQ
);
121 bi_depermanent(rsa_ctx
->qInv
);
122 bi_free(bi_ctx
, rsa_ctx
->dP
);
123 bi_free(bi_ctx
, rsa_ctx
->dQ
);
124 bi_free(bi_ctx
, rsa_ctx
->qInv
);
125 bi_free_mod(rsa_ctx
->bi_ctx
, BIGINT_P_OFFSET
);
126 bi_free_mod(rsa_ctx
->bi_ctx
, BIGINT_Q_OFFSET
);
130 bi_terminate(bi_ctx
);
135 * @brief Use PKCS1.5 for decryption/verification.
136 * @param ctx [in] The context
137 * @param in_data [in] The data to encrypt (must be < modulus size-11)
138 * @param out_data [out] The encrypted data.
139 * @param is_decryption [in] Decryption or verify operation.
140 * @return The number of bytes that were originally encrypted. -1 on error.
141 * @see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
143 int RSA_decrypt(const RSA_CTX
*ctx
, const uint8_t *in_data
,
144 uint8_t *out_data
, int is_decryption
)
146 const int byte_size
= ctx
->num_octets
;
148 bigint
*decrypted_bi
, *dat_bi
;
149 uint8_t *block
= (uint8_t *)alloca(byte_size
);
151 memset(out_data
, 0, byte_size
); /* initialise */
154 dat_bi
= bi_import(ctx
->bi_ctx
, in_data
, byte_size
);
155 #ifdef CONFIG_SSL_CERT_VERIFICATION
156 decrypted_bi
= is_decryption
? /* decrypt or verify? */
157 RSA_private(ctx
, dat_bi
) : RSA_public(ctx
, dat_bi
);
158 #else /* always a decryption */
159 decrypted_bi
= RSA_private(ctx
, dat_bi
);
162 /* convert to a normal block */
163 bi_export(ctx
->bi_ctx
, decrypted_bi
, block
, byte_size
);
165 i
= 10; /* start at the first possible non-padded byte */
167 #ifdef CONFIG_SSL_CERT_VERIFICATION
168 if (is_decryption
== 0) /* PKCS1.5 signing pads with "0xff"s */
170 while (block
[i
++] == 0xff && i
< byte_size
);
172 if (block
[i
-2] != 0xff)
173 i
= byte_size
; /*ensure size is 0 */
175 else /* PKCS1.5 encryption padding is random */
178 while (block
[i
++] && i
< byte_size
);
180 size
= byte_size
- i
;
182 /* get only the bit we want */
184 memcpy(out_data
, &block
[i
], size
);
186 return size
? size
: -1;
190 * Performs m = c^d mod n
192 bigint
*RSA_private(const RSA_CTX
*c
, bigint
*bi_msg
)
194 printf("RSA private\n");
195 #ifdef CONFIG_BIGINT_CRT
196 return bi_crt(c
->bi_ctx
, bi_msg
, c
->dP
, c
->dQ
, c
->p
, c
->q
, c
->qInv
);
198 BI_CTX
*ctx
= c
->bi_ctx
;
199 ctx
->mod_offset
= BIGINT_M_OFFSET
;
200 return bi_mod_power(ctx
, bi_msg
, c
->d
);
204 #ifdef CONFIG_SSL_FULL_MODE
206 * Used for diagnostics.
208 void RSA_print(const RSA_CTX
*rsa_ctx
)
213 printf("----------------- RSA DEBUG ----------------\n");
214 printf("Size:\t%d\n", rsa_ctx
->num_octets
);
215 bi_print("Modulus", rsa_ctx
->m
);
216 bi_print("Public Key", rsa_ctx
->e
);
217 bi_print("Private Key", rsa_ctx
->d
);
221 #if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT)
223 * Performs c = m^e mod n
225 bigint
*RSA_public(const RSA_CTX
* c
, bigint
*bi_msg
)
227 c
->bi_ctx
->mod_offset
= BIGINT_M_OFFSET
;
228 return bi_mod_power(c
->bi_ctx
, bi_msg
, c
->e
);
232 * Use PKCS1.5 for encryption/signing.
233 * see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
235 int RSA_encrypt(const RSA_CTX
*ctx
, const uint8_t *in_data
, uint16_t in_len
,
236 uint8_t *out_data
, int is_signing
)
238 int byte_size
= ctx
->num_octets
;
239 int num_pads_needed
= byte_size
-in_len
-3;
240 bigint
*dat_bi
, *encrypt_bi
;
241 /* note: in_len+11 must be > byte_size */
242 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
);
260 encrypt_bi
= is_signing
? RSA_private(ctx
, dat_bi
) :
261 RSA_public(ctx
, dat_bi
);
263 bi_export(ctx
->bi_ctx
, encrypt_bi
, out_data
, byte_size
);
264 /* save a few bytes of memory */
265 bi_clear_cache(ctx
->bi_ctx
);
270 #endif /* CONFIG_SSL_CERT_VERIFICATION */