2 * The RSA public-key cryptosystem
4 * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
6 * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * * Neither the names of PolarSSL or XySSL nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
38 * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
39 * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
42 #include "tropicssl/config.h"
44 #if defined(TROPICSSL_RSA_C)
46 #include "tropicssl/rsa.h"
53 * Initialize an RSA context
55 void rsa_init(rsa_context
* ctx
,
56 int padding
, int hash_id
, int (*f_rng
) (void *), void *p_rng
)
58 memset(ctx
, 0, sizeof(rsa_context
));
60 ctx
->padding
= padding
;
61 ctx
->hash_id
= hash_id
;
67 #if defined(TROPICSSL_GENPRIME)
70 * Generate an RSA keypair
72 int rsa_gen_key(rsa_context
* ctx
, int nbits
, int exponent
)
77 if (ctx
->f_rng
== NULL
|| nbits
< 128 || exponent
< 3)
78 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA
);
80 mpi_init(&P1
); mpi_init(&Q1
); mpi_init(&H
); mpi_init(&G
);
83 * find primes P and Q with Q < P so that:
84 * GCD( E, (P-1)*(Q-1) ) == 1
86 MPI_CHK(mpi_lset(&ctx
->E
, exponent
));
89 MPI_CHK(mpi_gen_prime(&ctx
->P
, (nbits
+ 1) >> 1, 0,
90 ctx
->f_rng
, ctx
->p_rng
));
92 MPI_CHK(mpi_gen_prime(&ctx
->Q
, (nbits
+ 1) >> 1, 0,
93 ctx
->f_rng
, ctx
->p_rng
));
95 if (mpi_cmp_mpi(&ctx
->P
, &ctx
->Q
) < 0)
96 mpi_swap(&ctx
->P
, &ctx
->Q
);
98 if (mpi_cmp_mpi(&ctx
->P
, &ctx
->Q
) == 0)
101 MPI_CHK(mpi_mul_mpi(&ctx
->N
, &ctx
->P
, &ctx
->Q
));
102 if (mpi_msb(&ctx
->N
) != nbits
)
105 MPI_CHK(mpi_sub_int(&P1
, &ctx
->P
, 1));
106 MPI_CHK(mpi_sub_int(&Q1
, &ctx
->Q
, 1));
107 MPI_CHK(mpi_mul_mpi(&H
, &P1
, &Q1
));
108 MPI_CHK(mpi_gcd(&G
, &ctx
->E
, &H
));
109 } while (mpi_cmp_int(&G
, 1) != 0);
112 * D = E^-1 mod ((P-1)*(Q-1))
117 MPI_CHK(mpi_inv_mod(&ctx
->D
, &ctx
->E
, &H
));
118 MPI_CHK(mpi_mod_mpi(&ctx
->DP
, &ctx
->D
, &P1
));
119 MPI_CHK(mpi_mod_mpi(&ctx
->DQ
, &ctx
->D
, &Q1
));
120 MPI_CHK(mpi_inv_mod(&ctx
->QP
, &ctx
->Q
, &ctx
->P
));
122 ctx
->len
= (mpi_msb(&ctx
->N
) + 7) >> 3;
126 mpi_free(&G
); mpi_free(&H
); mpi_free(&Q1
); mpi_free(&P1
);
130 return (TROPICSSL_ERR_RSA_KEY_GEN_FAILED
| ret
);
139 * Check a public RSA key
141 int rsa_check_pubkey(const rsa_context
* ctx
)
143 if ((ctx
->N
.p
[0] & 1) == 0 || (ctx
->E
.p
[0] & 1) == 0)
144 return (TROPICSSL_ERR_RSA_KEY_CHECK_FAILED
);
146 if (mpi_msb(&ctx
->N
) < 128 || mpi_msb(&ctx
->N
) > 4096)
147 return (TROPICSSL_ERR_RSA_KEY_CHECK_FAILED
);
149 if (mpi_msb(&ctx
->E
) < 2 || mpi_msb(&ctx
->E
) > 64)
150 return (TROPICSSL_ERR_RSA_KEY_CHECK_FAILED
);
156 * Check a private RSA key
158 int rsa_check_privkey(const rsa_context
* ctx
)
161 mpi PQ
, DE
, P1
, Q1
, H
, I
, G
;
163 if ((ret
= rsa_check_pubkey(ctx
)) != 0)
166 mpi_init(&PQ
); mpi_init(&DE
); mpi_init(&P1
); mpi_init(&Q1
);
167 mpi_init(&H
); mpi_init(&I
); mpi_init(&G
);
169 MPI_CHK(mpi_mul_mpi(&PQ
, &ctx
->P
, &ctx
->Q
));
170 MPI_CHK(mpi_mul_mpi(&DE
, &ctx
->D
, &ctx
->E
));
171 MPI_CHK(mpi_sub_int(&P1
, &ctx
->P
, 1));
172 MPI_CHK(mpi_sub_int(&Q1
, &ctx
->Q
, 1));
173 MPI_CHK(mpi_mul_mpi(&H
, &P1
, &Q1
));
174 MPI_CHK(mpi_mod_mpi(&I
, &DE
, &H
));
175 MPI_CHK(mpi_gcd(&G
, &ctx
->E
, &H
));
177 if (mpi_cmp_mpi(&PQ
, &ctx
->N
) == 0 &&
178 mpi_cmp_int(&I
, 1) == 0 && mpi_cmp_int(&G
, 1) == 0) {
179 mpi_free(&G
); mpi_free(&I
); mpi_free(&H
); mpi_free(&Q1
);
180 mpi_free(&P1
); mpi_free(&DE
); mpi_free(&PQ
);
186 mpi_free(&G
); mpi_free(&I
); mpi_free(&H
); mpi_free(&Q1
);
187 mpi_free(&P1
); mpi_free(&DE
); mpi_free(&PQ
);
188 return (TROPICSSL_ERR_RSA_KEY_CHECK_FAILED
| ret
);
192 * Do an RSA public key operation
194 int rsa_public(rsa_context
* ctx
, const unsigned char *input
, unsigned char *output
)
201 MPI_CHK(mpi_read_binary(&T
, input
, ctx
->len
));
203 if (mpi_cmp_mpi(&T
, &ctx
->N
) >= 0) {
205 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA
);
209 MPI_CHK(mpi_exp_mod(&T
, &T
, &ctx
->E
, &ctx
->N
, &ctx
->RN
));
210 MPI_CHK(mpi_write_binary(&T
, output
, olen
));
217 return (TROPICSSL_ERR_RSA_PUBLIC_FAILED
| ret
);
223 * Do an RSA private key operation
225 int rsa_private(rsa_context
* ctx
, const unsigned char *input
, unsigned char *output
)
230 mpi_init(&T
); mpi_init(&T1
); mpi_init(&T2
);
232 MPI_CHK(mpi_read_binary(&T
, input
, ctx
->len
));
234 if (mpi_cmp_mpi(&T
, &ctx
->N
) >= 0) {
236 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA
);
239 MPI_CHK(mpi_exp_mod(&T
, &T
, &ctx
->D
, &ctx
->N
, &ctx
->RN
));
242 * faster decryption using the CRT
244 * T1 = input ^ dP mod P
245 * T2 = input ^ dQ mod Q
247 MPI_CHK(mpi_exp_mod(&T1
, &T
, &ctx
->DP
, &ctx
->P
, &ctx
->RP
));
248 MPI_CHK(mpi_exp_mod(&T2
, &T
, &ctx
->DQ
, &ctx
->Q
, &ctx
->RQ
));
251 * T = (T1 - T2) * (Q^-1 mod P) mod P
253 MPI_CHK(mpi_sub_mpi(&T
, &T1
, &T2
));
254 MPI_CHK(mpi_mul_mpi(&T1
, &T
, &ctx
->QP
));
255 MPI_CHK(mpi_mod_mpi(&T
, &T1
, &ctx
->P
));
258 * output = T2 + T * Q
260 MPI_CHK(mpi_mul_mpi(&T1
, &T
, &ctx
->Q
));
261 MPI_CHK(mpi_add_mpi(&T
, &T2
, &T1
));
265 MPI_CHK(mpi_write_binary(&T
, output
, olen
));
269 mpi_free(&T
); mpi_free(&T1
); mpi_free(&T2
);
272 return (TROPICSSL_ERR_RSA_PRIVATE_FAILED
| ret
);
278 * Add the message padding, then do an RSA operation
280 int rsa_pkcs1_encrypt(rsa_context
* ctx
,
282 const unsigned char *input
,
283 unsigned char *output
)
286 unsigned char *p
= output
;
290 switch (ctx
->padding
) {
293 if (ilen
< 0 || olen
< ilen
+ 11)
294 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA
);
296 nb_pad
= olen
- 3 - ilen
;
301 while (nb_pad
-- > 0) {
303 *p
= (unsigned char)rand();
308 memcpy(p
, input
, ilen
);
313 return (TROPICSSL_ERR_RSA_INVALID_PADDING
);
316 return ((mode
== RSA_PUBLIC
)
317 ? rsa_public(ctx
, output
, output
)
318 : rsa_private(ctx
, output
, output
));
322 * Do an RSA operation, then remove the message padding
324 int rsa_pkcs1_decrypt(rsa_context
* ctx
,
326 const unsigned char *input
,
327 unsigned char *output
,
332 unsigned char buf
[512];
336 if (ilen
< 16 || ilen
> (int)sizeof(buf
))
337 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA
);
339 ret
= (mode
== RSA_PUBLIC
)
340 ? rsa_public(ctx
, input
, buf
)
341 : rsa_private(ctx
, input
, buf
);
348 switch (ctx
->padding
) {
351 if (*p
++ != 0 || *p
++ != RSA_CRYPT
)
352 return (TROPICSSL_ERR_RSA_INVALID_PADDING
);
355 if (p
>= buf
+ ilen
- 1)
356 return (TROPICSSL_ERR_RSA_INVALID_PADDING
);
364 return (TROPICSSL_ERR_RSA_INVALID_PADDING
);
367 if (ilen
- (int)(p
- buf
) > output_max_len
)
368 return (TROPICSSL_ERR_RSA_OUTPUT_TO_LARGE
);
370 *olen
= ilen
- (int)(p
- buf
);
371 memcpy(output
, p
, *olen
);
377 * Do an RSA operation to sign the message digest
379 int rsa_pkcs1_sign(rsa_context
* ctx
,
383 const unsigned char *hash
,
387 unsigned char *p
= sig
;
391 switch (ctx
->padding
) {
396 nb_pad
= olen
- 3 - hashlen
;
402 nb_pad
= olen
- 3 - 34;
406 nb_pad
= olen
- 3 - 35;
410 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA
);
414 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA
);
418 memset(p
, 0xFF, nb_pad
);
425 return (TROPICSSL_ERR_RSA_INVALID_PADDING
);
430 memcpy(p
, hash
, hashlen
);
434 memcpy(p
, ASN1_HASH_MDX
, 18);
435 memcpy(p
+ 18, hash
, 16);
440 memcpy(p
, ASN1_HASH_MDX
, 18);
441 memcpy(p
+ 18, hash
, 16);
446 memcpy(p
, ASN1_HASH_MDX
, 18);
447 memcpy(p
+ 18, hash
, 16);
452 memcpy(p
, ASN1_HASH_SHA1
, 15);
453 memcpy(p
+ 15, hash
, 20);
457 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA
);
460 return ((mode
== RSA_PUBLIC
)
461 ? rsa_public(ctx
, sig
, sig
)
462 : rsa_private(ctx
, sig
, sig
));
466 * Do an RSA operation and check the message digest
468 int rsa_pkcs1_verify(rsa_context
* ctx
,
472 const unsigned char *hash
,
473 const unsigned char *sig
)
475 int ret
, len
, siglen
;
477 unsigned char buf
[512];
481 if (siglen
< 16 || siglen
> (int)sizeof(buf
))
482 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA
);
484 ret
= (mode
== RSA_PUBLIC
)
485 ? rsa_public(ctx
, sig
, buf
)
486 : rsa_private(ctx
, sig
, buf
);
493 switch (ctx
->padding
) {
496 if (*p
++ != 0 || *p
++ != RSA_SIGN
)
497 return (TROPICSSL_ERR_RSA_INVALID_PADDING
);
500 if (p
>= buf
+ siglen
- 1 || *p
!= 0xFF)
501 return (TROPICSSL_ERR_RSA_INVALID_PADDING
);
509 return (TROPICSSL_ERR_RSA_INVALID_PADDING
);
512 len
= siglen
- (int)(p
- buf
);
518 if (memcmp(p
, ASN1_HASH_MDX
, 18) != 0)
519 return (TROPICSSL_ERR_RSA_VERIFY_FAILED
);
521 if ((c
== 2 && hash_id
== RSA_MD2
) ||
522 (c
== 4 && hash_id
== RSA_MD4
) ||
523 (c
== 5 && hash_id
== RSA_MD5
)) {
524 if (memcmp(p
+ 18, hash
, 16) == 0)
527 return (TROPICSSL_ERR_RSA_VERIFY_FAILED
);
531 if (len
== 35 && hash_id
== RSA_SHA1
) {
532 if (memcmp(p
, ASN1_HASH_SHA1
, 15) == 0 &&
533 memcmp(p
+ 15, hash
, 20) == 0)
536 return (TROPICSSL_ERR_RSA_VERIFY_FAILED
);
539 if (len
== hashlen
&& hash_id
== RSA_RAW
) {
540 if (memcmp(p
, hash
, hashlen
) == 0)
543 return (TROPICSSL_ERR_RSA_VERIFY_FAILED
);
546 return (TROPICSSL_ERR_RSA_INVALID_PADDING
);
550 * Free the components of an RSA key
552 void rsa_free(rsa_context
* ctx
)
554 mpi_free(&ctx
->RQ
); mpi_free(&ctx
->RP
); mpi_free(&ctx
->RN
);
555 mpi_free(&ctx
->QP
); mpi_free(&ctx
->DQ
); mpi_free(&ctx
->DP
);
556 mpi_free(&ctx
->Q
); mpi_free(&ctx
->P
); mpi_free(&ctx
->D
);
557 mpi_free(&ctx
->E
); mpi_free(&ctx
->N
);
560 #if defined(TROPICSSL_SELF_TEST)
562 #include "tropicssl/sha1.h"
565 * Example RSA-1024 keypair, for test purposes
569 #define RSA_N "9292758453063D803DD603D5E777D788" \
570 "8ED1D5BF35786190FA2F23EBC0848AEA" \
571 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
572 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
573 "93A89813FBF3C4F8066D2D800F7C38A8" \
574 "1AE31942917403FF4946B0A83D3D3E05" \
575 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
576 "5E94BB77B07507233A0BC7BAC8F90F79"
578 #define RSA_E "10001"
580 #define RSA_D "24BF6185468786FDD303083D25E64EFC" \
581 "66CA472BC44D253102F8B4A9D3BFA750" \
582 "91386C0077937FE33FA3252D28855837" \
583 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
584 "DF79C5CE07EE72C7F123142198164234" \
585 "CABB724CF78B8173B9F880FC86322407" \
586 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
587 "071513A1E85B5DFA031F21ECAE91A34D"
589 #define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
590 "2C01CAD19EA484A87EA4377637E75500" \
591 "FCB2005C5C7DD6EC4AC023CDA285D796" \
592 "C3D9E75E1EFC42488BB4F1D13AC30A57"
594 #define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
595 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
596 "910E4168387E3C30AA1E00C339A79508" \
597 "8452DD96A9A5EA5D9DCA68DA636032AF"
599 #define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
600 "3C94D22288ACD763FD8E5600ED4A702D" \
601 "F84198A5F06C2E72236AE490C93F07F8" \
602 "3CC559CD27BC2D1CA488811730BB5725"
604 #define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
605 "D8AAEA56749EA28623272E4F7D0592AF" \
606 "7C1F1313CAC9471B5C523BFE592F517B" \
607 "407A1BD76C164B93DA2D32A383E58357"
609 #define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
610 "F38D18D2B2F0E2DD275AA977E2BF4411" \
611 "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
612 "A74206CEC169D74BF5A8C50D6F48EA08"
615 #define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
616 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
621 int rsa_self_test(int verbose
)
625 unsigned char sha1sum
[20];
626 unsigned char rsa_plaintext
[PT_LEN
];
627 unsigned char rsa_decrypted
[PT_LEN
];
628 unsigned char rsa_ciphertext
[KEY_LEN
];
630 memset(&rsa
, 0, sizeof(rsa_context
));
633 mpi_read_string(&rsa
.N
, 16, RSA_N
);
634 mpi_read_string(&rsa
.E
, 16, RSA_E
);
635 mpi_read_string(&rsa
.D
, 16, RSA_D
);
636 mpi_read_string(&rsa
.P
, 16, RSA_P
);
637 mpi_read_string(&rsa
.Q
, 16, RSA_Q
);
638 mpi_read_string(&rsa
.DP
, 16, RSA_DP
);
639 mpi_read_string(&rsa
.DQ
, 16, RSA_DQ
);
640 mpi_read_string(&rsa
.QP
, 16, RSA_QP
);
643 printf(" RSA key validation: ");
645 if (rsa_check_pubkey(&rsa
) != 0 || rsa_check_privkey(&rsa
) != 0) {
653 printf("passed\n PKCS#1 encryption : ");
655 memcpy(rsa_plaintext
, RSA_PT
, PT_LEN
);
657 if (rsa_pkcs1_encrypt(&rsa
, RSA_PUBLIC
, PT_LEN
,
658 rsa_plaintext
, rsa_ciphertext
) != 0) {
666 printf("passed\n PKCS#1 decryption : ");
668 if (rsa_pkcs1_decrypt(&rsa
, RSA_PRIVATE
, &len
,
669 rsa_ciphertext
, rsa_decrypted
,
670 sizeof(rsa_decrypted
)) != 0) {
677 if (memcmp(rsa_decrypted
, rsa_plaintext
, len
) != 0) {
685 printf("passed\n PKCS#1 data sign : ");
687 sha1(rsa_plaintext
, PT_LEN
, sha1sum
);
689 if (rsa_pkcs1_sign(&rsa
, RSA_PRIVATE
, RSA_SHA1
, 20,
690 sha1sum
, rsa_ciphertext
) != 0) {
698 printf("passed\n PKCS#1 sig. verify: ");
700 if (rsa_pkcs1_verify(&rsa
, RSA_PUBLIC
, RSA_SHA1
, 20,
701 sha1sum
, rsa_ciphertext
) != 0) {
709 printf("passed\n\n");