blob: 6f22b095fff9cb664866a9280a0ecd4f3bf8094e [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
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
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020043#if defined(POLARSSL_MEMORY_C)
44#include "polarssl/memory.h"
45#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{
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +020060 return( 8 * ((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{
306 ((void) md_alg);
307
308 return( ecdsa_write_signature( (ecdsa_context *) ctx,
309 hash, hash_len, sig, sig_len, f_rng, p_rng ) );
310}
311
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200312static void *ecdsa_alloc_wrap( void )
313{
314 void *ctx = polarssl_malloc( sizeof( ecdsa_context ) );
315
316 if( ctx != NULL )
317 ecdsa_init( (ecdsa_context *) ctx );
318
319 return( ctx );
320}
321
322static void ecdsa_free_wrap( void *ctx )
323{
324 ecdsa_free( (ecdsa_context *) ctx );
325 polarssl_free( ctx );
326}
327
328const pk_info_t ecdsa_info = {
329 POLARSSL_PK_ECDSA,
330 "ECDSA",
331 eckey_get_size, /* Compatible key structures */
332 ecdsa_can_do,
333 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200334 ecdsa_sign_wrap,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200335 NULL,
336 NULL,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200337 ecdsa_alloc_wrap,
338 ecdsa_free_wrap,
339 eckey_debug, /* Compatible key structures */
340};
341#endif /* POLARSSL_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200342
343/*
344 * Support for alternative RSA-private implementations
345 */
346
347static size_t rsa_alt_get_size( const void *ctx )
348{
349 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
350
351 return( rsa_alt->key_len_func( rsa_alt->key ) );
352}
353
354static int rsa_alt_sign_wrap( void *ctx, md_type_t md_alg,
355 const unsigned char *hash, size_t hash_len,
356 unsigned char *sig, size_t *sig_len,
357 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
358{
359 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
360
361 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
362
363 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200364 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200365}
366
367static int rsa_alt_decrypt_wrap( void *ctx,
368 const unsigned char *input, size_t ilen,
369 unsigned char *output, size_t *olen, size_t osize,
370 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
371{
372 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
373
374 ((void) f_rng);
375 ((void) p_rng);
376
377 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
378 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
379
380 return( rsa_alt->decrypt_func( rsa_alt->key,
381 RSA_PRIVATE, olen, input, output, osize ) );
382}
383
384static void *rsa_alt_alloc_wrap( void )
385{
386 void *ctx = polarssl_malloc( sizeof( rsa_alt_context ) );
387
388 if( ctx != NULL )
389 memset( ctx, 0, sizeof( rsa_alt_context ) );
390
391 return ctx;
392}
393
394static void rsa_alt_free_wrap( void *ctx )
395{
396 polarssl_free( ctx );
397}
398
399const pk_info_t rsa_alt_info = {
400 POLARSSL_PK_RSA_ALT,
401 "RSA-alt",
402 rsa_alt_get_size,
403 rsa_can_do,
404 NULL,
405 rsa_alt_sign_wrap,
406 rsa_alt_decrypt_wrap,
407 NULL,
408 rsa_alt_alloc_wrap,
409 rsa_alt_free_wrap,
410 NULL,
411};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200412
413#endif /* POLARSSL_PK_C */