blob: a51d4f7f5e255a791774ea2ddb4cf0f6c2669241 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * The RSA public-key cryptosystem
3 *
Paul Bakkerfc8c4362010-03-21 17:37:16 +00004 * Copyright (C) 2006-2010, Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakker77b385e2009-07-28 17:23:11 +00005 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00006 *
Paul Bakker5121ce52009-01-03 21:22:43 +00007 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21/*
22 * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
23 *
24 * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
25 * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
26 */
27
Paul Bakker40e46942009-01-03 21:51:57 +000028#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Paul Bakker40e46942009-01-03 21:51:57 +000030#if defined(POLARSSL_RSA_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000031
Paul Bakker40e46942009-01-03 21:51:57 +000032#include "polarssl/rsa.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000033
34#include <stdlib.h>
35#include <string.h>
36#include <stdio.h>
37
38/*
39 * Initialize an RSA context
40 */
41void rsa_init( rsa_context *ctx,
42 int padding,
43 int hash_id,
44 int (*f_rng)(void *),
45 void *p_rng )
46{
47 memset( ctx, 0, sizeof( rsa_context ) );
48
49 ctx->padding = padding;
50 ctx->hash_id = hash_id;
51
52 ctx->f_rng = f_rng;
53 ctx->p_rng = p_rng;
54}
55
Paul Bakker40e46942009-01-03 21:51:57 +000056#if defined(POLARSSL_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +000057
58/*
59 * Generate an RSA keypair
60 */
61int rsa_gen_key( rsa_context *ctx, int nbits, int exponent )
62{
63 int ret;
64 mpi P1, Q1, H, G;
65
66 if( ctx->f_rng == NULL || nbits < 128 || exponent < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +000067 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000068
69 mpi_init( &P1, &Q1, &H, &G, NULL );
70
71 /*
72 * find primes P and Q with Q < P so that:
73 * GCD( E, (P-1)*(Q-1) ) == 1
74 */
75 MPI_CHK( mpi_lset( &ctx->E, exponent ) );
76
77 do
78 {
79 MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
80 ctx->f_rng, ctx->p_rng ) );
81
82 MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
83 ctx->f_rng, ctx->p_rng ) );
84
85 if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
86 mpi_swap( &ctx->P, &ctx->Q );
87
88 if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
89 continue;
90
91 MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
92 if( mpi_msb( &ctx->N ) != nbits )
93 continue;
94
95 MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
96 MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
97 MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
98 MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
99 }
100 while( mpi_cmp_int( &G, 1 ) != 0 );
101
102 /*
103 * D = E^-1 mod ((P-1)*(Q-1))
104 * DP = D mod (P - 1)
105 * DQ = D mod (Q - 1)
106 * QP = Q^-1 mod P
107 */
108 MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H ) );
109 MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
110 MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
111 MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );
112
113 ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3;
114
115cleanup:
116
117 mpi_free( &G, &H, &Q1, &P1, NULL );
118
119 if( ret != 0 )
120 {
121 rsa_free( ctx );
Paul Bakker40e46942009-01-03 21:51:57 +0000122 return( POLARSSL_ERR_RSA_KEY_GEN_FAILED | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000123 }
124
125 return( 0 );
126}
127
128#endif
129
130/*
131 * Check a public RSA key
132 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000133int rsa_check_pubkey( const rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000134{
Paul Bakker37940d9f2009-07-10 22:38:58 +0000135 if( !ctx->N.p || !ctx->E.p )
136 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
137
Paul Bakker5121ce52009-01-03 21:22:43 +0000138 if( ( ctx->N.p[0] & 1 ) == 0 ||
139 ( ctx->E.p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000140 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000141
142 if( mpi_msb( &ctx->N ) < 128 ||
143 mpi_msb( &ctx->N ) > 4096 )
Paul Bakker40e46942009-01-03 21:51:57 +0000144 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000145
146 if( mpi_msb( &ctx->E ) < 2 ||
147 mpi_msb( &ctx->E ) > 64 )
Paul Bakker40e46942009-01-03 21:51:57 +0000148 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000149
150 return( 0 );
151}
152
153/*
154 * Check a private RSA key
155 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000156int rsa_check_privkey( const rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000157{
158 int ret;
Paul Bakkerb572adf2010-07-18 08:29:32 +0000159 mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2;
Paul Bakker5121ce52009-01-03 21:22:43 +0000160
161 if( ( ret = rsa_check_pubkey( ctx ) ) != 0 )
162 return( ret );
163
Paul Bakker37940d9f2009-07-10 22:38:58 +0000164 if( !ctx->P.p || !ctx->Q.p || !ctx->D.p )
165 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
166
Paul Bakkerb572adf2010-07-18 08:29:32 +0000167 mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, &G2, &L1, &L2, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000168
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 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000174 MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
175
Paul Bakkerb572adf2010-07-18 08:29:32 +0000176 MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) );
177 MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) );
178 MPI_CHK( mpi_mod_mpi( &I, &DE, &L1 ) );
179
180 /*
181 * Check for a valid PKCS1v2 private key
182 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000183 if( mpi_cmp_mpi( &PQ, &ctx->N ) == 0 &&
Paul Bakkerb572adf2010-07-18 08:29:32 +0000184 mpi_cmp_int( &L2, 0 ) == 0 &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000185 mpi_cmp_int( &I, 1 ) == 0 &&
186 mpi_cmp_int( &G, 1 ) == 0 )
187 {
Paul Bakkerb572adf2010-07-18 08:29:32 +0000188 mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000189 return( 0 );
190 }
191
Paul Bakkerb572adf2010-07-18 08:29:32 +0000192
Paul Bakker5121ce52009-01-03 21:22:43 +0000193cleanup:
194
Paul Bakkerb572adf2010-07-18 08:29:32 +0000195 mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
Paul Bakker40e46942009-01-03 21:51:57 +0000196 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000197}
198
199/*
200 * Do an RSA public key operation
201 */
202int rsa_public( rsa_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000203 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000204 unsigned char *output )
205{
206 int ret, olen;
207 mpi T;
208
209 mpi_init( &T, NULL );
210
211 MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
212
213 if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
214 {
215 mpi_free( &T, NULL );
Paul Bakker40e46942009-01-03 21:51:57 +0000216 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000217 }
218
219 olen = ctx->len;
220 MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
221 MPI_CHK( mpi_write_binary( &T, output, olen ) );
222
223cleanup:
224
225 mpi_free( &T, NULL );
226
227 if( ret != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000228 return( POLARSSL_ERR_RSA_PUBLIC_FAILED | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000229
230 return( 0 );
231}
232
233/*
234 * Do an RSA private key operation
235 */
236int rsa_private( rsa_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000237 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000238 unsigned char *output )
239{
240 int ret, olen;
241 mpi T, T1, T2;
242
243 mpi_init( &T, &T1, &T2, NULL );
244
245 MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
246
247 if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
248 {
249 mpi_free( &T, NULL );
Paul Bakker40e46942009-01-03 21:51:57 +0000250 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000251 }
252
253#if 0
254 MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
255#else
256 /*
257 * faster decryption using the CRT
258 *
259 * T1 = input ^ dP mod P
260 * T2 = input ^ dQ mod Q
261 */
262 MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
263 MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );
264
265 /*
266 * T = (T1 - T2) * (Q^-1 mod P) mod P
267 */
268 MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) );
269 MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) );
270 MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) );
271
272 /*
273 * output = T2 + T * Q
274 */
275 MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) );
276 MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) );
277#endif
278
279 olen = ctx->len;
280 MPI_CHK( mpi_write_binary( &T, output, olen ) );
281
282cleanup:
283
284 mpi_free( &T, &T1, &T2, NULL );
285
286 if( ret != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000287 return( POLARSSL_ERR_RSA_PRIVATE_FAILED | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000288
289 return( 0 );
290}
291
292/*
293 * Add the message padding, then do an RSA operation
294 */
295int rsa_pkcs1_encrypt( rsa_context *ctx,
296 int mode, int ilen,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000297 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000298 unsigned char *output )
299{
300 int nb_pad, olen;
301 unsigned char *p = output;
302
303 olen = ctx->len;
304
305 switch( ctx->padding )
306 {
307 case RSA_PKCS_V15:
308
Paul Bakkerb572adf2010-07-18 08:29:32 +0000309 if( ilen < 0 || olen < ilen + 11 || ctx->f_rng == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000310 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000311
312 nb_pad = olen - 3 - ilen;
313
314 *p++ = 0;
315 *p++ = RSA_CRYPT;
316
317 while( nb_pad-- > 0 )
318 {
Paul Bakkerb572adf2010-07-18 08:29:32 +0000319 int rng_dl = 100;
320
Paul Bakker5121ce52009-01-03 21:22:43 +0000321 do {
Paul Bakkerb572adf2010-07-18 08:29:32 +0000322 *p = (unsigned char) ctx->f_rng( ctx->p_rng );
323 } while( *p == 0 && --rng_dl );
324
325 // Check if RNG failed to generate data
326 //
327 if( rng_dl == 0 )
328 return POLARSSL_ERR_RSA_RNG_FAILED;
329
Paul Bakker5121ce52009-01-03 21:22:43 +0000330 p++;
331 }
332 *p++ = 0;
333 memcpy( p, input, ilen );
334 break;
335
336 default:
337
Paul Bakker40e46942009-01-03 21:51:57 +0000338 return( POLARSSL_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +0000339 }
340
341 return( ( mode == RSA_PUBLIC )
342 ? rsa_public( ctx, output, output )
343 : rsa_private( ctx, output, output ) );
344}
345
346/*
347 * Do an RSA operation, then remove the message padding
348 */
349int rsa_pkcs1_decrypt( rsa_context *ctx,
350 int mode, int *olen,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000351 const unsigned char *input,
Paul Bakker060c5682009-01-12 21:48:39 +0000352 unsigned char *output,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000353 int output_max_len)
Paul Bakker5121ce52009-01-03 21:22:43 +0000354{
355 int ret, ilen;
356 unsigned char *p;
Paul Bakkercde51572009-05-17 10:11:56 +0000357 unsigned char buf[1024];
Paul Bakker5121ce52009-01-03 21:22:43 +0000358
359 ilen = ctx->len;
360
361 if( ilen < 16 || ilen > (int) sizeof( buf ) )
Paul Bakker40e46942009-01-03 21:51:57 +0000362 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000363
364 ret = ( mode == RSA_PUBLIC )
365 ? rsa_public( ctx, input, buf )
366 : rsa_private( ctx, input, buf );
367
368 if( ret != 0 )
369 return( ret );
370
371 p = buf;
372
373 switch( ctx->padding )
374 {
375 case RSA_PKCS_V15:
376
377 if( *p++ != 0 || *p++ != RSA_CRYPT )
Paul Bakker40e46942009-01-03 21:51:57 +0000378 return( POLARSSL_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +0000379
380 while( *p != 0 )
381 {
382 if( p >= buf + ilen - 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000383 return( POLARSSL_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +0000384 p++;
385 }
386 p++;
387 break;
388
389 default:
390
Paul Bakker40e46942009-01-03 21:51:57 +0000391 return( POLARSSL_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +0000392 }
393
Paul Bakker060c5682009-01-12 21:48:39 +0000394 if (ilen - (int)(p - buf) > output_max_len)
Paul Bakker38e2b482009-07-19 20:41:06 +0000395 return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
Paul Bakker060c5682009-01-12 21:48:39 +0000396
Paul Bakker5121ce52009-01-03 21:22:43 +0000397 *olen = ilen - (int)(p - buf);
398 memcpy( output, p, *olen );
399
400 return( 0 );
401}
402
403/*
404 * Do an RSA operation to sign the message digest
405 */
406int rsa_pkcs1_sign( rsa_context *ctx,
407 int mode,
408 int hash_id,
409 int hashlen,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000410 const unsigned char *hash,
Paul Bakker5121ce52009-01-03 21:22:43 +0000411 unsigned char *sig )
412{
413 int nb_pad, olen;
414 unsigned char *p = sig;
415
416 olen = ctx->len;
417
418 switch( ctx->padding )
419 {
420 case RSA_PKCS_V15:
421
422 switch( hash_id )
423 {
Paul Bakkerfc22c442009-07-19 20:36:27 +0000424 case SIG_RSA_RAW:
Paul Bakker5121ce52009-01-03 21:22:43 +0000425 nb_pad = olen - 3 - hashlen;
426 break;
427
Paul Bakker4593aea2009-02-09 22:32:35 +0000428 case SIG_RSA_MD2:
429 case SIG_RSA_MD4:
430 case SIG_RSA_MD5:
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 nb_pad = olen - 3 - 34;
432 break;
433
Paul Bakker4593aea2009-02-09 22:32:35 +0000434 case SIG_RSA_SHA1:
Paul Bakker5121ce52009-01-03 21:22:43 +0000435 nb_pad = olen - 3 - 35;
436 break;
437
Paul Bakkercde51572009-05-17 10:11:56 +0000438 case SIG_RSA_SHA224:
439 nb_pad = olen - 3 - 47;
440 break;
441
442 case SIG_RSA_SHA256:
443 nb_pad = olen - 3 - 51;
444 break;
445
446 case SIG_RSA_SHA384:
447 nb_pad = olen - 3 - 67;
448 break;
449
450 case SIG_RSA_SHA512:
451 nb_pad = olen - 3 - 83;
452 break;
453
454
Paul Bakker5121ce52009-01-03 21:22:43 +0000455 default:
Paul Bakker40e46942009-01-03 21:51:57 +0000456 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000457 }
458
459 if( nb_pad < 8 )
Paul Bakker40e46942009-01-03 21:51:57 +0000460 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
462 *p++ = 0;
463 *p++ = RSA_SIGN;
464 memset( p, 0xFF, nb_pad );
465 p += nb_pad;
466 *p++ = 0;
467 break;
468
469 default:
470
Paul Bakker40e46942009-01-03 21:51:57 +0000471 return( POLARSSL_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +0000472 }
473
474 switch( hash_id )
475 {
Paul Bakkerfc22c442009-07-19 20:36:27 +0000476 case SIG_RSA_RAW:
Paul Bakker5121ce52009-01-03 21:22:43 +0000477 memcpy( p, hash, hashlen );
478 break;
479
Paul Bakker4593aea2009-02-09 22:32:35 +0000480 case SIG_RSA_MD2:
Paul Bakker5121ce52009-01-03 21:22:43 +0000481 memcpy( p, ASN1_HASH_MDX, 18 );
482 memcpy( p + 18, hash, 16 );
483 p[13] = 2; break;
484
Paul Bakker4593aea2009-02-09 22:32:35 +0000485 case SIG_RSA_MD4:
Paul Bakker5121ce52009-01-03 21:22:43 +0000486 memcpy( p, ASN1_HASH_MDX, 18 );
487 memcpy( p + 18, hash, 16 );
488 p[13] = 4; break;
489
Paul Bakker4593aea2009-02-09 22:32:35 +0000490 case SIG_RSA_MD5:
Paul Bakker5121ce52009-01-03 21:22:43 +0000491 memcpy( p, ASN1_HASH_MDX, 18 );
492 memcpy( p + 18, hash, 16 );
493 p[13] = 5; break;
494
Paul Bakker4593aea2009-02-09 22:32:35 +0000495 case SIG_RSA_SHA1:
Paul Bakker5121ce52009-01-03 21:22:43 +0000496 memcpy( p, ASN1_HASH_SHA1, 15 );
497 memcpy( p + 15, hash, 20 );
498 break;
499
Paul Bakker4593aea2009-02-09 22:32:35 +0000500 case SIG_RSA_SHA224:
501 memcpy( p, ASN1_HASH_SHA2X, 19 );
502 memcpy( p + 19, hash, 28 );
503 p[1] += 28; p[14] = 4; p[18] += 28; break;
504
505 case SIG_RSA_SHA256:
506 memcpy( p, ASN1_HASH_SHA2X, 19 );
507 memcpy( p + 19, hash, 32 );
508 p[1] += 32; p[14] = 1; p[18] += 32; break;
509
510 case SIG_RSA_SHA384:
511 memcpy( p, ASN1_HASH_SHA2X, 19 );
512 memcpy( p + 19, hash, 48 );
513 p[1] += 48; p[14] = 2; p[18] += 48; break;
514
515 case SIG_RSA_SHA512:
516 memcpy( p, ASN1_HASH_SHA2X, 19 );
517 memcpy( p + 19, hash, 64 );
518 p[1] += 64; p[14] = 3; p[18] += 64; break;
519
Paul Bakker5121ce52009-01-03 21:22:43 +0000520 default:
Paul Bakker40e46942009-01-03 21:51:57 +0000521 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000522 }
523
524 return( ( mode == RSA_PUBLIC )
525 ? rsa_public( ctx, sig, sig )
526 : rsa_private( ctx, sig, sig ) );
527}
528
529/*
530 * Do an RSA operation and check the message digest
531 */
532int rsa_pkcs1_verify( rsa_context *ctx,
533 int mode,
534 int hash_id,
535 int hashlen,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000536 const unsigned char *hash,
Paul Bakker5121ce52009-01-03 21:22:43 +0000537 unsigned char *sig )
538{
539 int ret, len, siglen;
540 unsigned char *p, c;
Paul Bakkercde51572009-05-17 10:11:56 +0000541 unsigned char buf[1024];
Paul Bakker5121ce52009-01-03 21:22:43 +0000542
543 siglen = ctx->len;
544
545 if( siglen < 16 || siglen > (int) sizeof( buf ) )
Paul Bakker40e46942009-01-03 21:51:57 +0000546 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000547
548 ret = ( mode == RSA_PUBLIC )
549 ? rsa_public( ctx, sig, buf )
550 : rsa_private( ctx, sig, buf );
551
552 if( ret != 0 )
553 return( ret );
554
555 p = buf;
556
557 switch( ctx->padding )
558 {
559 case RSA_PKCS_V15:
560
561 if( *p++ != 0 || *p++ != RSA_SIGN )
Paul Bakker40e46942009-01-03 21:51:57 +0000562 return( POLARSSL_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +0000563
564 while( *p != 0 )
565 {
566 if( p >= buf + siglen - 1 || *p != 0xFF )
Paul Bakker40e46942009-01-03 21:51:57 +0000567 return( POLARSSL_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +0000568 p++;
569 }
570 p++;
571 break;
572
573 default:
574
Paul Bakker40e46942009-01-03 21:51:57 +0000575 return( POLARSSL_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +0000576 }
577
578 len = siglen - (int)( p - buf );
579
580 if( len == 34 )
581 {
582 c = p[13];
583 p[13] = 0;
584
585 if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000586 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000587
Paul Bakker4593aea2009-02-09 22:32:35 +0000588 if( ( c == 2 && hash_id == SIG_RSA_MD2 ) ||
589 ( c == 4 && hash_id == SIG_RSA_MD4 ) ||
590 ( c == 5 && hash_id == SIG_RSA_MD5 ) )
Paul Bakker5121ce52009-01-03 21:22:43 +0000591 {
592 if( memcmp( p + 18, hash, 16 ) == 0 )
593 return( 0 );
594 else
Paul Bakker40e46942009-01-03 21:51:57 +0000595 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000596 }
597 }
598
Paul Bakker4593aea2009-02-09 22:32:35 +0000599 if( len == 35 && hash_id == SIG_RSA_SHA1 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000600 {
601 if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
602 memcmp( p + 15, hash, 20 ) == 0 )
603 return( 0 );
604 else
Paul Bakker40e46942009-01-03 21:51:57 +0000605 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000606 }
Paul Bakker4593aea2009-02-09 22:32:35 +0000607 if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) ||
608 ( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) ||
609 ( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
610 ( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
611 {
612 c = p[1] - 17;
Paul Bakkercde51572009-05-17 10:11:56 +0000613 p[1] = 17;
614 p[14] = 0;
Paul Bakker4593aea2009-02-09 22:32:35 +0000615
616 if( p[18] == c &&
Paul Bakkercde51572009-05-17 10:11:56 +0000617 memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 &&
618 memcmp( p + 19, hash, c ) == 0 )
619 return( 0 );
620 else
621 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
Paul Bakker4593aea2009-02-09 22:32:35 +0000622 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000623
Paul Bakkerfc22c442009-07-19 20:36:27 +0000624 if( len == hashlen && hash_id == SIG_RSA_RAW )
Paul Bakker5121ce52009-01-03 21:22:43 +0000625 {
626 if( memcmp( p, hash, hashlen ) == 0 )
627 return( 0 );
628 else
Paul Bakker40e46942009-01-03 21:51:57 +0000629 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000630 }
631
Paul Bakker40e46942009-01-03 21:51:57 +0000632 return( POLARSSL_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +0000633}
634
635/*
636 * Free the components of an RSA key
637 */
638void rsa_free( rsa_context *ctx )
639{
640 mpi_free( &ctx->RQ, &ctx->RP, &ctx->RN,
641 &ctx->QP, &ctx->DQ, &ctx->DP,
642 &ctx->Q, &ctx->P, &ctx->D,
643 &ctx->E, &ctx->N, NULL );
644}
645
Paul Bakker40e46942009-01-03 21:51:57 +0000646#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000647
Paul Bakker40e46942009-01-03 21:51:57 +0000648#include "polarssl/sha1.h"
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
650/*
651 * Example RSA-1024 keypair, for test purposes
652 */
653#define KEY_LEN 128
654
655#define RSA_N "9292758453063D803DD603D5E777D788" \
656 "8ED1D5BF35786190FA2F23EBC0848AEA" \
657 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
658 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
659 "93A89813FBF3C4F8066D2D800F7C38A8" \
660 "1AE31942917403FF4946B0A83D3D3E05" \
661 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
662 "5E94BB77B07507233A0BC7BAC8F90F79"
663
664#define RSA_E "10001"
665
666#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
667 "66CA472BC44D253102F8B4A9D3BFA750" \
668 "91386C0077937FE33FA3252D28855837" \
669 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
670 "DF79C5CE07EE72C7F123142198164234" \
671 "CABB724CF78B8173B9F880FC86322407" \
672 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
673 "071513A1E85B5DFA031F21ECAE91A34D"
674
675#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
676 "2C01CAD19EA484A87EA4377637E75500" \
677 "FCB2005C5C7DD6EC4AC023CDA285D796" \
678 "C3D9E75E1EFC42488BB4F1D13AC30A57"
679
680#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
681 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
682 "910E4168387E3C30AA1E00C339A79508" \
683 "8452DD96A9A5EA5D9DCA68DA636032AF"
684
685#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
686 "3C94D22288ACD763FD8E5600ED4A702D" \
687 "F84198A5F06C2E72236AE490C93F07F8" \
688 "3CC559CD27BC2D1CA488811730BB5725"
689
690#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
691 "D8AAEA56749EA28623272E4F7D0592AF" \
692 "7C1F1313CAC9471B5C523BFE592F517B" \
693 "407A1BD76C164B93DA2D32A383E58357"
694
695#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
696 "F38D18D2B2F0E2DD275AA977E2BF4411" \
697 "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
698 "A74206CEC169D74BF5A8C50D6F48EA08"
699
700#define PT_LEN 24
701#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
702 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
703
Paul Bakker545570e2010-07-18 09:00:25 +0000704static int myrand( void *rng_state )
705{
706 if( rng_state != NULL )
707 rng_state = NULL;
708
709 return( rand() );
710}
711
Paul Bakker5121ce52009-01-03 21:22:43 +0000712/*
713 * Checkup routine
714 */
715int rsa_self_test( int verbose )
716{
717 int len;
718 rsa_context rsa;
719 unsigned char sha1sum[20];
720 unsigned char rsa_plaintext[PT_LEN];
721 unsigned char rsa_decrypted[PT_LEN];
722 unsigned char rsa_ciphertext[KEY_LEN];
723
Paul Bakker545570e2010-07-18 09:00:25 +0000724 rsa_init( &rsa, RSA_PKCS_V15, 0, &myrand, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000725
726 rsa.len = KEY_LEN;
727 mpi_read_string( &rsa.N , 16, RSA_N );
728 mpi_read_string( &rsa.E , 16, RSA_E );
729 mpi_read_string( &rsa.D , 16, RSA_D );
730 mpi_read_string( &rsa.P , 16, RSA_P );
731 mpi_read_string( &rsa.Q , 16, RSA_Q );
732 mpi_read_string( &rsa.DP, 16, RSA_DP );
733 mpi_read_string( &rsa.DQ, 16, RSA_DQ );
734 mpi_read_string( &rsa.QP, 16, RSA_QP );
735
736 if( verbose != 0 )
737 printf( " RSA key validation: " );
738
739 if( rsa_check_pubkey( &rsa ) != 0 ||
740 rsa_check_privkey( &rsa ) != 0 )
741 {
742 if( verbose != 0 )
743 printf( "failed\n" );
744
745 return( 1 );
746 }
747
748 if( verbose != 0 )
749 printf( "passed\n PKCS#1 encryption : " );
750
751 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
752
753 if( rsa_pkcs1_encrypt( &rsa, RSA_PUBLIC, PT_LEN,
754 rsa_plaintext, rsa_ciphertext ) != 0 )
755 {
756 if( verbose != 0 )
757 printf( "failed\n" );
758
759 return( 1 );
760 }
761
762 if( verbose != 0 )
763 printf( "passed\n PKCS#1 decryption : " );
764
765 if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len,
Paul Bakker060c5682009-01-12 21:48:39 +0000766 rsa_ciphertext, rsa_decrypted,
767 sizeof(rsa_decrypted) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000768 {
769 if( verbose != 0 )
770 printf( "failed\n" );
771
772 return( 1 );
773 }
774
775 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
776 {
777 if( verbose != 0 )
778 printf( "failed\n" );
779
780 return( 1 );
781 }
782
783 if( verbose != 0 )
784 printf( "passed\n PKCS#1 data sign : " );
785
786 sha1( rsa_plaintext, PT_LEN, sha1sum );
787
Paul Bakker4593aea2009-02-09 22:32:35 +0000788 if( rsa_pkcs1_sign( &rsa, RSA_PRIVATE, SIG_RSA_SHA1, 20,
Paul Bakker5121ce52009-01-03 21:22:43 +0000789 sha1sum, rsa_ciphertext ) != 0 )
790 {
791 if( verbose != 0 )
792 printf( "failed\n" );
793
794 return( 1 );
795 }
796
797 if( verbose != 0 )
798 printf( "passed\n PKCS#1 sig. verify: " );
799
Paul Bakker4593aea2009-02-09 22:32:35 +0000800 if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1, 20,
Paul Bakker5121ce52009-01-03 21:22:43 +0000801 sha1sum, rsa_ciphertext ) != 0 )
802 {
803 if( verbose != 0 )
804 printf( "failed\n" );
805
806 return( 1 );
807 }
808
809 if( verbose != 0 )
810 printf( "passed\n\n" );
811
812 rsa_free( &rsa );
813
814 return( 0 );
815}
816
817#endif
818
819#endif