blob: 2a4da03d87733c85f5b2dc385766e8b50fc296b1 [file] [log] [blame]
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +02001/*
2 * Public Key abstraction layer: wrapper functions
3 *
Paul Bakker7dc4c442014-02-01 22:50:26 +01004 * Copyright (C) 2006-2014, Brainspark B.V.
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +02005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#include "polarssl/config.h"
27
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +020028#if defined(POLARSSL_PK_C)
29
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020030#include "polarssl/pk_wrap.h"
31
Manuel Pégourié-Gonnarde511ffc2013-08-22 17:33:21 +020032/* Even if RSA not activated, for the sake of RSA-alt */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020033#include "polarssl/rsa.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020034
35#if defined(POLARSSL_ECP_C)
36#include "polarssl/ecp.h"
37#endif
38
39#if defined(POLARSSL_ECDSA_C)
40#include "polarssl/ecdsa.h"
41#endif
42
Paul Bakker7dc4c442014-02-01 22:50:26 +010043#if defined(POLARSSL_PLATFORM_C)
44#include "polarssl/platform.h"
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020045#else
46#include <stdlib.h>
47#define polarssl_malloc malloc
48#define polarssl_free free
49#endif
50
Manuel Pégourié-Gonnarde511ffc2013-08-22 17:33:21 +020051/* Used by RSA-alt too */
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020052static int rsa_can_do( pk_type_t type )
53{
54 return( type == POLARSSL_PK_RSA );
55}
56
Manuel Pégourié-Gonnarde511ffc2013-08-22 17:33:21 +020057#if defined(POLARSSL_RSA_C)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +020058static size_t rsa_get_size( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020059{
Paul Bakker8fc30b12013-11-25 13:29:43 +010060 return( 8 * ((const rsa_context *) ctx)->len );
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020061}
62
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +020063static int rsa_verify_wrap( void *ctx, md_type_t md_alg,
64 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020065 const unsigned char *sig, size_t sig_len )
66{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +020067 int ret;
68
69 if( sig_len < ((rsa_context *) ctx)->len )
Manuel Pégourié-Gonnardac4cd362013-08-14 20:20:41 +020070 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020071
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +020072 if( ( ret = rsa_pkcs1_verify( (rsa_context *) ctx, NULL, NULL,
73 RSA_PUBLIC, md_alg,
74 (unsigned int) hash_len, hash, sig ) ) != 0 )
75 return( ret );
76
77 if( sig_len > ((rsa_context *) ctx)->len )
78 return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH );
79
80 return( 0 );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020081}
82
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +020083static int rsa_sign_wrap( void *ctx, md_type_t md_alg,
84 const unsigned char *hash, size_t hash_len,
85 unsigned char *sig, size_t *sig_len,
86 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
87{
88 *sig_len = ((rsa_context *) ctx)->len;
89
90 return( rsa_pkcs1_sign( (rsa_context *) ctx, f_rng, p_rng, RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +020091 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +020092}
93
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +020094static int rsa_decrypt_wrap( void *ctx,
95 const unsigned char *input, size_t ilen,
96 unsigned char *output, size_t *olen, size_t osize,
97 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
98{
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +020099 if( ilen != ((rsa_context *) ctx)->len )
100 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
101
Paul Bakker548957d2013-08-30 10:30:02 +0200102 return( rsa_pkcs1_decrypt( (rsa_context *) ctx, f_rng, p_rng,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200103 RSA_PRIVATE, olen, input, output, osize ) );
104}
105
106static int rsa_encrypt_wrap( void *ctx,
107 const unsigned char *input, size_t ilen,
108 unsigned char *output, size_t *olen, size_t osize,
109 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
110{
111 ((void) osize);
112
113 *olen = ((rsa_context *) ctx)->len;
114
115 return( rsa_pkcs1_encrypt( (rsa_context *) ctx,
116 f_rng, p_rng, RSA_PUBLIC, ilen, input, output ) );
117}
118
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200119static void *rsa_alloc_wrap( void )
120{
121 void *ctx = polarssl_malloc( sizeof( rsa_context ) );
122
123 if( ctx != NULL )
124 rsa_init( (rsa_context *) ctx, 0, 0 );
125
126 return ctx;
127}
128
129static void rsa_free_wrap( void *ctx )
130{
131 rsa_free( (rsa_context *) ctx );
132 polarssl_free( ctx );
133}
134
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200135static void rsa_debug( const void *ctx, pk_debug_item *items )
136{
137 items->type = POLARSSL_PK_DEBUG_MPI;
138 items->name = "rsa.N";
139 items->value = &( ((rsa_context *) ctx)->N );
140
141 items++;
142
143 items->type = POLARSSL_PK_DEBUG_MPI;
144 items->name = "rsa.E";
145 items->value = &( ((rsa_context *) ctx)->E );
146}
147
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200148const pk_info_t rsa_info = {
149 POLARSSL_PK_RSA,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200150 "RSA",
151 rsa_get_size,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200152 rsa_can_do,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200153 rsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200154 rsa_sign_wrap,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200155 rsa_decrypt_wrap,
156 rsa_encrypt_wrap,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200157 rsa_alloc_wrap,
158 rsa_free_wrap,
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200159 rsa_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200160};
161#endif /* POLARSSL_RSA_C */
162
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200163#if defined(POLARSSL_ECP_C)
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200164/*
165 * Generic EC key
166 */
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200167static int eckey_can_do( pk_type_t type )
168{
169 return( type == POLARSSL_PK_ECKEY ||
170 type == POLARSSL_PK_ECKEY_DH ||
171 type == POLARSSL_PK_ECDSA );
172}
173
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200174static size_t eckey_get_size( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200175{
176 return( ((ecp_keypair *) ctx)->grp.pbits );
177}
178
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200179#if defined(POLARSSL_ECDSA_C)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200180/* Forward declarations */
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200181static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg,
182 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200183 const unsigned char *sig, size_t sig_len );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200184
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200185static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg,
186 const unsigned char *hash, size_t hash_len,
187 unsigned char *sig, size_t *sig_len,
188 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
189
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200190static int eckey_verify_wrap( void *ctx, md_type_t md_alg,
191 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200192 const unsigned char *sig, size_t sig_len )
193{
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200194 int ret;
195 ecdsa_context ecdsa;
196
197 ecdsa_init( &ecdsa );
198
Manuel Pégourié-Gonnard583b6082013-08-20 16:58:13 +0200199 if( ( ret = ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
200 ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200201
202 ecdsa_free( &ecdsa );
203
204 return( ret );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200205}
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200206
207static int eckey_sign_wrap( void *ctx, md_type_t md_alg,
208 const unsigned char *hash, size_t hash_len,
209 unsigned char *sig, size_t *sig_len,
210 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
211{
212 int ret;
213 ecdsa_context ecdsa;
214
215 ecdsa_init( &ecdsa );
216
217 if( ( ret = ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
218 ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
219 f_rng, p_rng );
220
221 ecdsa_free( &ecdsa );
222
223 return( ret );
224}
225
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200226#endif /* POLARSSL_ECDSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200227
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200228static void *eckey_alloc_wrap( void )
229{
230 void *ctx = polarssl_malloc( sizeof( ecp_keypair ) );
231
232 if( ctx != NULL )
233 ecp_keypair_init( ctx );
234
235 return( ctx );
236}
237
238static void eckey_free_wrap( void *ctx )
239{
240 ecp_keypair_free( (ecp_keypair *) ctx );
241 polarssl_free( ctx );
242}
243
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200244static void eckey_debug( const void *ctx, pk_debug_item *items )
245{
246 items->type = POLARSSL_PK_DEBUG_ECP;
247 items->name = "eckey.Q";
248 items->value = &( ((ecp_keypair *) ctx)->Q );
249}
250
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200251const pk_info_t eckey_info = {
252 POLARSSL_PK_ECKEY,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200253 "EC",
254 eckey_get_size,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200255 eckey_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200256#if defined(POLARSSL_ECDSA_C)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200257 eckey_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200258 eckey_sign_wrap,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200259#else
260 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200261 NULL,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200262#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200263 NULL,
264 NULL,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200265 eckey_alloc_wrap,
266 eckey_free_wrap,
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200267 eckey_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200268};
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200269
270/*
Paul Bakker75342a62014-04-08 17:35:40 +0200271 * EC key restricted to ECDH
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200272 */
273static int eckeydh_can_do( pk_type_t type )
274{
275 return( type == POLARSSL_PK_ECKEY ||
276 type == POLARSSL_PK_ECKEY_DH );
277}
278
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200279const pk_info_t eckeydh_info = {
280 POLARSSL_PK_ECKEY_DH,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200281 "EC_DH",
282 eckey_get_size, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200283 eckeydh_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200284 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200285 NULL,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200286 NULL,
287 NULL,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200288 eckey_alloc_wrap, /* Same underlying key structure */
289 eckey_free_wrap, /* Same underlying key structure */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200290 eckey_debug, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200291};
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200292#endif /* POLARSSL_ECP_C */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200293
294#if defined(POLARSSL_ECDSA_C)
295static int ecdsa_can_do( pk_type_t type )
296{
297 return( type == POLARSSL_PK_ECDSA );
298}
299
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200300static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg,
301 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200302 const unsigned char *sig, size_t sig_len )
303{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200304 int ret;
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200305 ((void) md_alg);
306
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200307 ret = ecdsa_read_signature( (ecdsa_context *) ctx,
308 hash, hash_len, sig, sig_len );
309
310 if( ret == POLARSSL_ERR_ECP_SIG_LEN_MISMATCH )
311 return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH );
312
313 return( ret );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200314}
315
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200316static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg,
317 const unsigned char *hash, size_t hash_len,
318 unsigned char *sig, size_t *sig_len,
319 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
320{
Manuel Pégourié-Gonnard65ad3e42014-01-06 16:57:24 +0100321 /* Use deterministic ECDSA by default if available */
322#if defined(POLARSSL_ECDSA_DETERMINISTIC)
323 ((void) f_rng);
324 ((void) p_rng);
325
326 return( ecdsa_write_signature_det( (ecdsa_context *) ctx,
327 hash, hash_len, sig, sig_len, md_alg ) );
328#else
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200329 ((void) md_alg);
330
331 return( ecdsa_write_signature( (ecdsa_context *) ctx,
332 hash, hash_len, sig, sig_len, f_rng, p_rng ) );
Manuel Pégourié-Gonnard65ad3e42014-01-06 16:57:24 +0100333#endif
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200334}
335
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200336static void *ecdsa_alloc_wrap( void )
337{
338 void *ctx = polarssl_malloc( sizeof( ecdsa_context ) );
339
340 if( ctx != NULL )
341 ecdsa_init( (ecdsa_context *) ctx );
342
343 return( ctx );
344}
345
346static void ecdsa_free_wrap( void *ctx )
347{
348 ecdsa_free( (ecdsa_context *) ctx );
349 polarssl_free( ctx );
350}
351
352const pk_info_t ecdsa_info = {
353 POLARSSL_PK_ECDSA,
354 "ECDSA",
355 eckey_get_size, /* Compatible key structures */
356 ecdsa_can_do,
357 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200358 ecdsa_sign_wrap,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200359 NULL,
360 NULL,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200361 ecdsa_alloc_wrap,
362 ecdsa_free_wrap,
363 eckey_debug, /* Compatible key structures */
364};
365#endif /* POLARSSL_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200366
367/*
368 * Support for alternative RSA-private implementations
369 */
370
371static size_t rsa_alt_get_size( const void *ctx )
372{
Paul Bakker8fc30b12013-11-25 13:29:43 +0100373 const rsa_alt_context *rsa_alt = (const rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200374
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200375 return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200376}
377
378static int rsa_alt_sign_wrap( void *ctx, md_type_t md_alg,
379 const unsigned char *hash, size_t hash_len,
380 unsigned char *sig, size_t *sig_len,
381 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
382{
383 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
384
385 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
386
387 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200388 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200389}
390
391static int rsa_alt_decrypt_wrap( void *ctx,
392 const unsigned char *input, size_t ilen,
393 unsigned char *output, size_t *olen, size_t osize,
394 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
395{
396 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
397
398 ((void) f_rng);
399 ((void) p_rng);
400
401 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
402 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
403
404 return( rsa_alt->decrypt_func( rsa_alt->key,
405 RSA_PRIVATE, olen, input, output, osize ) );
406}
407
408static void *rsa_alt_alloc_wrap( void )
409{
410 void *ctx = polarssl_malloc( sizeof( rsa_alt_context ) );
411
412 if( ctx != NULL )
413 memset( ctx, 0, sizeof( rsa_alt_context ) );
414
415 return ctx;
416}
417
418static void rsa_alt_free_wrap( void *ctx )
419{
420 polarssl_free( ctx );
421}
422
423const pk_info_t rsa_alt_info = {
424 POLARSSL_PK_RSA_ALT,
425 "RSA-alt",
426 rsa_alt_get_size,
427 rsa_can_do,
428 NULL,
429 rsa_alt_sign_wrap,
430 rsa_alt_decrypt_wrap,
431 NULL,
432 rsa_alt_alloc_wrap,
433 rsa_alt_free_wrap,
434 NULL,
435};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200436
437#endif /* POLARSSL_PK_C */