blob: 9f650b631343de2bb507de3ec45f392c4ffb3f9f [file] [log] [blame]
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +02001/*
2 * Public Key abstraction layer: wrapper functions
3 *
4 * Copyright (C) 2006-2013, Brainspark B.V.
5 *
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
28#include "polarssl/pk_wrap.h"
29
30#if defined(POLARSSL_RSA_C)
31#include "polarssl/rsa.h"
32#endif
33
34#if defined(POLARSSL_ECP_C)
35#include "polarssl/ecp.h"
36#endif
37
38#if defined(POLARSSL_ECDSA_C)
39#include "polarssl/ecdsa.h"
40#endif
41
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020042#if defined(POLARSSL_MEMORY_C)
43#include "polarssl/memory.h"
44#else
45#include <stdlib.h>
46#define polarssl_malloc malloc
47#define polarssl_free free
48#endif
49
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020050#if defined(POLARSSL_RSA_C)
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020051static int rsa_can_do( pk_type_t type )
52{
53 return( type == POLARSSL_PK_RSA );
54}
55
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +020056static size_t rsa_get_size( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020057{
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +020058 return( 8 * ((rsa_context *) ctx)->len );
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020059}
60
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +020061static int rsa_verify_wrap( void *ctx, md_type_t md_alg,
62 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020063 const unsigned char *sig, size_t sig_len )
64{
Manuel Pégourié-Gonnardac4cd362013-08-14 20:20:41 +020065 if( sig_len != ((rsa_context *) ctx)->len )
66 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020067
68 return( rsa_pkcs1_verify( (rsa_context *) ctx,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +020069 RSA_PUBLIC, md_alg, hash_len, hash, sig ) );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020070}
71
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +020072static int rsa_sign_wrap( void *ctx, md_type_t md_alg,
73 const unsigned char *hash, size_t hash_len,
74 unsigned char *sig, size_t *sig_len,
75 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
76{
77 *sig_len = ((rsa_context *) ctx)->len;
78
79 return( rsa_pkcs1_sign( (rsa_context *) ctx, f_rng, p_rng, RSA_PRIVATE,
80 md_alg, hash_len, hash, sig ) );
81}
82
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +020083static int rsa_decrypt_wrap( void *ctx,
84 const unsigned char *input, size_t ilen,
85 unsigned char *output, size_t *olen, size_t osize,
86 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
87{
88 ((void) f_rng);
89 ((void) p_rng);
90
91 if( ilen != ((rsa_context *) ctx)->len )
92 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
93
94 return( rsa_pkcs1_decrypt( (rsa_context *) ctx,
95 RSA_PRIVATE, olen, input, output, osize ) );
96}
97
98static int rsa_encrypt_wrap( void *ctx,
99 const unsigned char *input, size_t ilen,
100 unsigned char *output, size_t *olen, size_t osize,
101 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
102{
103 ((void) osize);
104
105 *olen = ((rsa_context *) ctx)->len;
106
107 return( rsa_pkcs1_encrypt( (rsa_context *) ctx,
108 f_rng, p_rng, RSA_PUBLIC, ilen, input, output ) );
109}
110
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200111static void *rsa_alloc_wrap( void )
112{
113 void *ctx = polarssl_malloc( sizeof( rsa_context ) );
114
115 if( ctx != NULL )
116 rsa_init( (rsa_context *) ctx, 0, 0 );
117
118 return ctx;
119}
120
121static void rsa_free_wrap( void *ctx )
122{
123 rsa_free( (rsa_context *) ctx );
124 polarssl_free( ctx );
125}
126
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200127static void rsa_debug( const void *ctx, pk_debug_item *items )
128{
129 items->type = POLARSSL_PK_DEBUG_MPI;
130 items->name = "rsa.N";
131 items->value = &( ((rsa_context *) ctx)->N );
132
133 items++;
134
135 items->type = POLARSSL_PK_DEBUG_MPI;
136 items->name = "rsa.E";
137 items->value = &( ((rsa_context *) ctx)->E );
138}
139
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200140const pk_info_t rsa_info = {
141 POLARSSL_PK_RSA,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200142 "RSA",
143 rsa_get_size,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200144 rsa_can_do,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200145 rsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200146 rsa_sign_wrap,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200147 rsa_decrypt_wrap,
148 rsa_encrypt_wrap,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200149 rsa_alloc_wrap,
150 rsa_free_wrap,
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200151 rsa_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200152};
153#endif /* POLARSSL_RSA_C */
154
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200155#if defined(POLARSSL_ECP_C)
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200156/*
157 * Generic EC key
158 */
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200159static int eckey_can_do( pk_type_t type )
160{
161 return( type == POLARSSL_PK_ECKEY ||
162 type == POLARSSL_PK_ECKEY_DH ||
163 type == POLARSSL_PK_ECDSA );
164}
165
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200166static size_t eckey_get_size( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200167{
168 return( ((ecp_keypair *) ctx)->grp.pbits );
169}
170
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200171#if defined(POLARSSL_ECDSA_C)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200172/* Forward declarations */
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200173static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg,
174 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200175 const unsigned char *sig, size_t sig_len );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200176
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200177static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg,
178 const unsigned char *hash, size_t hash_len,
179 unsigned char *sig, size_t *sig_len,
180 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
181
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200182static int eckey_verify_wrap( void *ctx, md_type_t md_alg,
183 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200184 const unsigned char *sig, size_t sig_len )
185{
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200186 int ret;
187 ecdsa_context ecdsa;
188
189 ecdsa_init( &ecdsa );
190
Manuel Pégourié-Gonnard583b6082013-08-20 16:58:13 +0200191 if( ( ret = ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
192 ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200193
194 ecdsa_free( &ecdsa );
195
196 return( ret );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200197}
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200198
199static int eckey_sign_wrap( void *ctx, md_type_t md_alg,
200 const unsigned char *hash, size_t hash_len,
201 unsigned char *sig, size_t *sig_len,
202 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
203{
204 int ret;
205 ecdsa_context ecdsa;
206
207 ecdsa_init( &ecdsa );
208
209 if( ( ret = ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
210 ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
211 f_rng, p_rng );
212
213 ecdsa_free( &ecdsa );
214
215 return( ret );
216}
217
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200218#endif /* POLARSSL_ECDSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200219
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200220static void *eckey_alloc_wrap( void )
221{
222 void *ctx = polarssl_malloc( sizeof( ecp_keypair ) );
223
224 if( ctx != NULL )
225 ecp_keypair_init( ctx );
226
227 return( ctx );
228}
229
230static void eckey_free_wrap( void *ctx )
231{
232 ecp_keypair_free( (ecp_keypair *) ctx );
233 polarssl_free( ctx );
234}
235
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200236static void eckey_debug( const void *ctx, pk_debug_item *items )
237{
238 items->type = POLARSSL_PK_DEBUG_ECP;
239 items->name = "eckey.Q";
240 items->value = &( ((ecp_keypair *) ctx)->Q );
241}
242
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200243const pk_info_t eckey_info = {
244 POLARSSL_PK_ECKEY,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200245 "EC",
246 eckey_get_size,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200247 eckey_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200248#if defined(POLARSSL_ECDSA_C)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200249 eckey_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200250 eckey_sign_wrap,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200251#else
252 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200253 NULL,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200254#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200255 NULL,
256 NULL,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200257 eckey_alloc_wrap,
258 eckey_free_wrap,
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200259 eckey_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200260};
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200261
262/*
263 * EC key resticted to ECDH
264 */
265static int eckeydh_can_do( pk_type_t type )
266{
267 return( type == POLARSSL_PK_ECKEY ||
268 type == POLARSSL_PK_ECKEY_DH );
269}
270
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200271const pk_info_t eckeydh_info = {
272 POLARSSL_PK_ECKEY_DH,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200273 "EC_DH",
274 eckey_get_size, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200275 eckeydh_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200276 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200277 NULL,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200278 NULL,
279 NULL,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200280 eckey_alloc_wrap, /* Same underlying key structure */
281 eckey_free_wrap, /* Same underlying key structure */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200282 eckey_debug, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200283};
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200284#endif /* POLARSSL_ECP_C */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200285
286#if defined(POLARSSL_ECDSA_C)
287static int ecdsa_can_do( pk_type_t type )
288{
289 return( type == POLARSSL_PK_ECDSA );
290}
291
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200292static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg,
293 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200294 const unsigned char *sig, size_t sig_len )
295{
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200296 ((void) md_alg);
297
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200298 return( ecdsa_read_signature( (ecdsa_context *) ctx,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200299 hash, hash_len, sig, sig_len ) );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200300}
301
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200302static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg,
303 const unsigned char *hash, size_t hash_len,
304 unsigned char *sig, size_t *sig_len,
305 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
306{
307 ((void) md_alg);
308
309 return( ecdsa_write_signature( (ecdsa_context *) ctx,
310 hash, hash_len, sig, sig_len, f_rng, p_rng ) );
311}
312
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200313static void *ecdsa_alloc_wrap( void )
314{
315 void *ctx = polarssl_malloc( sizeof( ecdsa_context ) );
316
317 if( ctx != NULL )
318 ecdsa_init( (ecdsa_context *) ctx );
319
320 return( ctx );
321}
322
323static void ecdsa_free_wrap( void *ctx )
324{
325 ecdsa_free( (ecdsa_context *) ctx );
326 polarssl_free( ctx );
327}
328
329const pk_info_t ecdsa_info = {
330 POLARSSL_PK_ECDSA,
331 "ECDSA",
332 eckey_get_size, /* Compatible key structures */
333 ecdsa_can_do,
334 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200335 ecdsa_sign_wrap,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200336 NULL,
337 NULL,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200338 ecdsa_alloc_wrap,
339 ecdsa_free_wrap,
340 eckey_debug, /* Compatible key structures */
341};
342#endif /* POLARSSL_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200343
344/*
345 * Support for alternative RSA-private implementations
346 */
347
348static size_t rsa_alt_get_size( const void *ctx )
349{
350 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
351
352 return( rsa_alt->key_len_func( rsa_alt->key ) );
353}
354
355static int rsa_alt_sign_wrap( void *ctx, md_type_t md_alg,
356 const unsigned char *hash, size_t hash_len,
357 unsigned char *sig, size_t *sig_len,
358 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
359{
360 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
361
362 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
363
364 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, RSA_PRIVATE,
365 md_alg, hash_len, hash, sig ) );
366}
367
368static int rsa_alt_decrypt_wrap( void *ctx,
369 const unsigned char *input, size_t ilen,
370 unsigned char *output, size_t *olen, size_t osize,
371 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
372{
373 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
374
375 ((void) f_rng);
376 ((void) p_rng);
377
378 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
379 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
380
381 return( rsa_alt->decrypt_func( rsa_alt->key,
382 RSA_PRIVATE, olen, input, output, osize ) );
383}
384
385static void *rsa_alt_alloc_wrap( void )
386{
387 void *ctx = polarssl_malloc( sizeof( rsa_alt_context ) );
388
389 if( ctx != NULL )
390 memset( ctx, 0, sizeof( rsa_alt_context ) );
391
392 return ctx;
393}
394
395static void rsa_alt_free_wrap( void *ctx )
396{
397 polarssl_free( ctx );
398}
399
400const pk_info_t rsa_alt_info = {
401 POLARSSL_PK_RSA_ALT,
402 "RSA-alt",
403 rsa_alt_get_size,
404 rsa_can_do,
405 NULL,
406 rsa_alt_sign_wrap,
407 rsa_alt_decrypt_wrap,
408 NULL,
409 rsa_alt_alloc_wrap,
410 rsa_alt_free_wrap,
411 NULL,
412};