blob: 99535d6138a0cf85d93e4110594462d4f3cce0f0 [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é-Gonnardac4cd362013-08-14 20:20:41 +020067 if( sig_len != ((rsa_context *) ctx)->len )
68 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020069
Paul Bakker548957d2013-08-30 10:30:02 +020070 return( rsa_pkcs1_verify( (rsa_context *) ctx, NULL, NULL,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +020071 RSA_PUBLIC, md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020072}
73
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +020074static int rsa_sign_wrap( void *ctx, md_type_t md_alg,
75 const unsigned char *hash, size_t hash_len,
76 unsigned char *sig, size_t *sig_len,
77 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
78{
79 *sig_len = ((rsa_context *) ctx)->len;
80
81 return( rsa_pkcs1_sign( (rsa_context *) ctx, f_rng, p_rng, RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +020082 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +020083}
84
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +020085static int rsa_decrypt_wrap( void *ctx,
86 const unsigned char *input, size_t ilen,
87 unsigned char *output, size_t *olen, size_t osize,
88 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
89{
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +020090 if( ilen != ((rsa_context *) ctx)->len )
91 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
92
Paul Bakker548957d2013-08-30 10:30:02 +020093 return( rsa_pkcs1_decrypt( (rsa_context *) ctx, f_rng, p_rng,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +020094 RSA_PRIVATE, olen, input, output, osize ) );
95}
96
97static int rsa_encrypt_wrap( void *ctx,
98 const unsigned char *input, size_t ilen,
99 unsigned char *output, size_t *olen, size_t osize,
100 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
101{
102 ((void) osize);
103
104 *olen = ((rsa_context *) ctx)->len;
105
106 return( rsa_pkcs1_encrypt( (rsa_context *) ctx,
107 f_rng, p_rng, RSA_PUBLIC, ilen, input, output ) );
108}
109
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200110static void *rsa_alloc_wrap( void )
111{
112 void *ctx = polarssl_malloc( sizeof( rsa_context ) );
113
114 if( ctx != NULL )
115 rsa_init( (rsa_context *) ctx, 0, 0 );
116
117 return ctx;
118}
119
120static void rsa_free_wrap( void *ctx )
121{
122 rsa_free( (rsa_context *) ctx );
123 polarssl_free( ctx );
124}
125
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200126static void rsa_debug( const void *ctx, pk_debug_item *items )
127{
128 items->type = POLARSSL_PK_DEBUG_MPI;
129 items->name = "rsa.N";
130 items->value = &( ((rsa_context *) ctx)->N );
131
132 items++;
133
134 items->type = POLARSSL_PK_DEBUG_MPI;
135 items->name = "rsa.E";
136 items->value = &( ((rsa_context *) ctx)->E );
137}
138
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200139const pk_info_t rsa_info = {
140 POLARSSL_PK_RSA,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200141 "RSA",
142 rsa_get_size,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200143 rsa_can_do,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200144 rsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200145 rsa_sign_wrap,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200146 rsa_decrypt_wrap,
147 rsa_encrypt_wrap,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200148 rsa_alloc_wrap,
149 rsa_free_wrap,
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200150 rsa_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200151};
152#endif /* POLARSSL_RSA_C */
153
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200154#if defined(POLARSSL_ECP_C)
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200155/*
156 * Generic EC key
157 */
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200158static int eckey_can_do( pk_type_t type )
159{
160 return( type == POLARSSL_PK_ECKEY ||
161 type == POLARSSL_PK_ECKEY_DH ||
162 type == POLARSSL_PK_ECDSA );
163}
164
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200165static size_t eckey_get_size( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200166{
167 return( ((ecp_keypair *) ctx)->grp.pbits );
168}
169
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200170#if defined(POLARSSL_ECDSA_C)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200171/* Forward declarations */
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200172static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg,
173 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200174 const unsigned char *sig, size_t sig_len );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200175
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200176static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg,
177 const unsigned char *hash, size_t hash_len,
178 unsigned char *sig, size_t *sig_len,
179 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
180
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200181static int eckey_verify_wrap( void *ctx, md_type_t md_alg,
182 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200183 const unsigned char *sig, size_t sig_len )
184{
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200185 int ret;
186 ecdsa_context ecdsa;
187
188 ecdsa_init( &ecdsa );
189
Manuel Pégourié-Gonnard583b6082013-08-20 16:58:13 +0200190 if( ( ret = ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
191 ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200192
193 ecdsa_free( &ecdsa );
194
195 return( ret );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200196}
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200197
198static int eckey_sign_wrap( void *ctx, md_type_t md_alg,
199 const unsigned char *hash, size_t hash_len,
200 unsigned char *sig, size_t *sig_len,
201 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
202{
203 int ret;
204 ecdsa_context ecdsa;
205
206 ecdsa_init( &ecdsa );
207
208 if( ( ret = ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
209 ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
210 f_rng, p_rng );
211
212 ecdsa_free( &ecdsa );
213
214 return( ret );
215}
216
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200217#endif /* POLARSSL_ECDSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200218
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200219static void *eckey_alloc_wrap( void )
220{
221 void *ctx = polarssl_malloc( sizeof( ecp_keypair ) );
222
223 if( ctx != NULL )
224 ecp_keypair_init( ctx );
225
226 return( ctx );
227}
228
229static void eckey_free_wrap( void *ctx )
230{
231 ecp_keypair_free( (ecp_keypair *) ctx );
232 polarssl_free( ctx );
233}
234
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200235static void eckey_debug( const void *ctx, pk_debug_item *items )
236{
237 items->type = POLARSSL_PK_DEBUG_ECP;
238 items->name = "eckey.Q";
239 items->value = &( ((ecp_keypair *) ctx)->Q );
240}
241
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200242const pk_info_t eckey_info = {
243 POLARSSL_PK_ECKEY,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200244 "EC",
245 eckey_get_size,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200246 eckey_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200247#if defined(POLARSSL_ECDSA_C)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200248 eckey_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200249 eckey_sign_wrap,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200250#else
251 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200252 NULL,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200253#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200254 NULL,
255 NULL,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200256 eckey_alloc_wrap,
257 eckey_free_wrap,
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200258 eckey_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200259};
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200260
261/*
262 * EC key resticted to ECDH
263 */
264static int eckeydh_can_do( pk_type_t type )
265{
266 return( type == POLARSSL_PK_ECKEY ||
267 type == POLARSSL_PK_ECKEY_DH );
268}
269
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200270const pk_info_t eckeydh_info = {
271 POLARSSL_PK_ECKEY_DH,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200272 "EC_DH",
273 eckey_get_size, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200274 eckeydh_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200275 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200276 NULL,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200277 NULL,
278 NULL,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200279 eckey_alloc_wrap, /* Same underlying key structure */
280 eckey_free_wrap, /* Same underlying key structure */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200281 eckey_debug, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200282};
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200283#endif /* POLARSSL_ECP_C */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200284
285#if defined(POLARSSL_ECDSA_C)
286static int ecdsa_can_do( pk_type_t type )
287{
288 return( type == POLARSSL_PK_ECDSA );
289}
290
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200291static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg,
292 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200293 const unsigned char *sig, size_t sig_len )
294{
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200295 ((void) md_alg);
296
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200297 return( ecdsa_read_signature( (ecdsa_context *) ctx,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200298 hash, hash_len, sig, sig_len ) );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200299}
300
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200301static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg,
302 const unsigned char *hash, size_t hash_len,
303 unsigned char *sig, size_t *sig_len,
304 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
305{
Manuel Pégourié-Gonnard65ad3e42014-01-06 16:57:24 +0100306 /* Use deterministic ECDSA by default if available */
307#if defined(POLARSSL_ECDSA_DETERMINISTIC)
308 ((void) f_rng);
309 ((void) p_rng);
310
311 return( ecdsa_write_signature_det( (ecdsa_context *) ctx,
312 hash, hash_len, sig, sig_len, md_alg ) );
313#else
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200314 ((void) md_alg);
315
316 return( ecdsa_write_signature( (ecdsa_context *) ctx,
317 hash, hash_len, sig, sig_len, f_rng, p_rng ) );
Manuel Pégourié-Gonnard65ad3e42014-01-06 16:57:24 +0100318#endif
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200319}
320
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200321static void *ecdsa_alloc_wrap( void )
322{
323 void *ctx = polarssl_malloc( sizeof( ecdsa_context ) );
324
325 if( ctx != NULL )
326 ecdsa_init( (ecdsa_context *) ctx );
327
328 return( ctx );
329}
330
331static void ecdsa_free_wrap( void *ctx )
332{
333 ecdsa_free( (ecdsa_context *) ctx );
334 polarssl_free( ctx );
335}
336
337const pk_info_t ecdsa_info = {
338 POLARSSL_PK_ECDSA,
339 "ECDSA",
340 eckey_get_size, /* Compatible key structures */
341 ecdsa_can_do,
342 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200343 ecdsa_sign_wrap,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200344 NULL,
345 NULL,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200346 ecdsa_alloc_wrap,
347 ecdsa_free_wrap,
348 eckey_debug, /* Compatible key structures */
349};
350#endif /* POLARSSL_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200351
352/*
353 * Support for alternative RSA-private implementations
354 */
355
356static size_t rsa_alt_get_size( const void *ctx )
357{
Paul Bakker8fc30b12013-11-25 13:29:43 +0100358 const rsa_alt_context *rsa_alt = (const rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200359
360 return( rsa_alt->key_len_func( rsa_alt->key ) );
361}
362
363static int rsa_alt_sign_wrap( void *ctx, md_type_t md_alg,
364 const unsigned char *hash, size_t hash_len,
365 unsigned char *sig, size_t *sig_len,
366 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
367{
368 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
369
370 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
371
372 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200373 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200374}
375
376static int rsa_alt_decrypt_wrap( void *ctx,
377 const unsigned char *input, size_t ilen,
378 unsigned char *output, size_t *olen, size_t osize,
379 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
380{
381 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
382
383 ((void) f_rng);
384 ((void) p_rng);
385
386 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
387 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
388
389 return( rsa_alt->decrypt_func( rsa_alt->key,
390 RSA_PRIVATE, olen, input, output, osize ) );
391}
392
393static void *rsa_alt_alloc_wrap( void )
394{
395 void *ctx = polarssl_malloc( sizeof( rsa_alt_context ) );
396
397 if( ctx != NULL )
398 memset( ctx, 0, sizeof( rsa_alt_context ) );
399
400 return ctx;
401}
402
403static void rsa_alt_free_wrap( void *ctx )
404{
405 polarssl_free( ctx );
406}
407
408const pk_info_t rsa_alt_info = {
409 POLARSSL_PK_RSA_ALT,
410 "RSA-alt",
411 rsa_alt_get_size,
412 rsa_can_do,
413 NULL,
414 rsa_alt_sign_wrap,
415 rsa_alt_decrypt_wrap,
416 NULL,
417 rsa_alt_alloc_wrap,
418 rsa_alt_free_wrap,
419 NULL,
420};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200421
422#endif /* POLARSSL_PK_C */