blob: 94f5282e2124cfcbafe8ce9aad30894fb1db08f2 [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
70 return( rsa_pkcs1_verify( (rsa_context *) ctx,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +020071 RSA_PUBLIC, md_alg, 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,
82 md_alg, hash_len, hash, sig ) );
83}
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{
90 ((void) f_rng);
91 ((void) p_rng);
92
93 if( ilen != ((rsa_context *) ctx)->len )
94 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
95
96 return( rsa_pkcs1_decrypt( (rsa_context *) ctx,
97 RSA_PRIVATE, olen, input, output, osize ) );
98}
99
100static int rsa_encrypt_wrap( void *ctx,
101 const unsigned char *input, size_t ilen,
102 unsigned char *output, size_t *olen, size_t osize,
103 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
104{
105 ((void) osize);
106
107 *olen = ((rsa_context *) ctx)->len;
108
109 return( rsa_pkcs1_encrypt( (rsa_context *) ctx,
110 f_rng, p_rng, RSA_PUBLIC, ilen, input, output ) );
111}
112
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200113static void *rsa_alloc_wrap( void )
114{
115 void *ctx = polarssl_malloc( sizeof( rsa_context ) );
116
117 if( ctx != NULL )
118 rsa_init( (rsa_context *) ctx, 0, 0 );
119
120 return ctx;
121}
122
123static void rsa_free_wrap( void *ctx )
124{
125 rsa_free( (rsa_context *) ctx );
126 polarssl_free( ctx );
127}
128
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200129static void rsa_debug( const void *ctx, pk_debug_item *items )
130{
131 items->type = POLARSSL_PK_DEBUG_MPI;
132 items->name = "rsa.N";
133 items->value = &( ((rsa_context *) ctx)->N );
134
135 items++;
136
137 items->type = POLARSSL_PK_DEBUG_MPI;
138 items->name = "rsa.E";
139 items->value = &( ((rsa_context *) ctx)->E );
140}
141
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200142const pk_info_t rsa_info = {
143 POLARSSL_PK_RSA,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200144 "RSA",
145 rsa_get_size,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200146 rsa_can_do,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200147 rsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200148 rsa_sign_wrap,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200149 rsa_decrypt_wrap,
150 rsa_encrypt_wrap,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200151 rsa_alloc_wrap,
152 rsa_free_wrap,
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200153 rsa_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200154};
155#endif /* POLARSSL_RSA_C */
156
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200157#if defined(POLARSSL_ECP_C)
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200158/*
159 * Generic EC key
160 */
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200161static int eckey_can_do( pk_type_t type )
162{
163 return( type == POLARSSL_PK_ECKEY ||
164 type == POLARSSL_PK_ECKEY_DH ||
165 type == POLARSSL_PK_ECDSA );
166}
167
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200168static size_t eckey_get_size( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200169{
170 return( ((ecp_keypair *) ctx)->grp.pbits );
171}
172
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200173#if defined(POLARSSL_ECDSA_C)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200174/* Forward declarations */
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200175static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg,
176 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200177 const unsigned char *sig, size_t sig_len );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200178
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200179static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg,
180 const unsigned char *hash, size_t hash_len,
181 unsigned char *sig, size_t *sig_len,
182 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
183
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200184static int eckey_verify_wrap( void *ctx, md_type_t md_alg,
185 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200186 const unsigned char *sig, size_t sig_len )
187{
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200188 int ret;
189 ecdsa_context ecdsa;
190
191 ecdsa_init( &ecdsa );
192
Manuel Pégourié-Gonnard583b6082013-08-20 16:58:13 +0200193 if( ( ret = ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
194 ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200195
196 ecdsa_free( &ecdsa );
197
198 return( ret );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200199}
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200200
201static int eckey_sign_wrap( void *ctx, md_type_t md_alg,
202 const unsigned char *hash, size_t hash_len,
203 unsigned char *sig, size_t *sig_len,
204 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
205{
206 int ret;
207 ecdsa_context ecdsa;
208
209 ecdsa_init( &ecdsa );
210
211 if( ( ret = ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
212 ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
213 f_rng, p_rng );
214
215 ecdsa_free( &ecdsa );
216
217 return( ret );
218}
219
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200220#endif /* POLARSSL_ECDSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200221
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200222static void *eckey_alloc_wrap( void )
223{
224 void *ctx = polarssl_malloc( sizeof( ecp_keypair ) );
225
226 if( ctx != NULL )
227 ecp_keypair_init( ctx );
228
229 return( ctx );
230}
231
232static void eckey_free_wrap( void *ctx )
233{
234 ecp_keypair_free( (ecp_keypair *) ctx );
235 polarssl_free( ctx );
236}
237
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200238static void eckey_debug( const void *ctx, pk_debug_item *items )
239{
240 items->type = POLARSSL_PK_DEBUG_ECP;
241 items->name = "eckey.Q";
242 items->value = &( ((ecp_keypair *) ctx)->Q );
243}
244
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200245const pk_info_t eckey_info = {
246 POLARSSL_PK_ECKEY,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200247 "EC",
248 eckey_get_size,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200249 eckey_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200250#if defined(POLARSSL_ECDSA_C)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200251 eckey_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200252 eckey_sign_wrap,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200253#else
254 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200255 NULL,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200256#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200257 NULL,
258 NULL,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200259 eckey_alloc_wrap,
260 eckey_free_wrap,
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200261 eckey_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200262};
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200263
264/*
265 * EC key resticted to ECDH
266 */
267static int eckeydh_can_do( pk_type_t type )
268{
269 return( type == POLARSSL_PK_ECKEY ||
270 type == POLARSSL_PK_ECKEY_DH );
271}
272
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200273const pk_info_t eckeydh_info = {
274 POLARSSL_PK_ECKEY_DH,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200275 "EC_DH",
276 eckey_get_size, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200277 eckeydh_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200278 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200279 NULL,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200280 NULL,
281 NULL,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200282 eckey_alloc_wrap, /* Same underlying key structure */
283 eckey_free_wrap, /* Same underlying key structure */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200284 eckey_debug, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200285};
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200286#endif /* POLARSSL_ECP_C */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200287
288#if defined(POLARSSL_ECDSA_C)
289static int ecdsa_can_do( pk_type_t type )
290{
291 return( type == POLARSSL_PK_ECDSA );
292}
293
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200294static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg,
295 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200296 const unsigned char *sig, size_t sig_len )
297{
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200298 ((void) md_alg);
299
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200300 return( ecdsa_read_signature( (ecdsa_context *) ctx,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200301 hash, hash_len, sig, sig_len ) );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200302}
303
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200304static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg,
305 const unsigned char *hash, size_t hash_len,
306 unsigned char *sig, size_t *sig_len,
307 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
308{
309 ((void) md_alg);
310
311 return( ecdsa_write_signature( (ecdsa_context *) ctx,
312 hash, hash_len, sig, sig_len, f_rng, p_rng ) );
313}
314
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200315static void *ecdsa_alloc_wrap( void )
316{
317 void *ctx = polarssl_malloc( sizeof( ecdsa_context ) );
318
319 if( ctx != NULL )
320 ecdsa_init( (ecdsa_context *) ctx );
321
322 return( ctx );
323}
324
325static void ecdsa_free_wrap( void *ctx )
326{
327 ecdsa_free( (ecdsa_context *) ctx );
328 polarssl_free( ctx );
329}
330
331const pk_info_t ecdsa_info = {
332 POLARSSL_PK_ECDSA,
333 "ECDSA",
334 eckey_get_size, /* Compatible key structures */
335 ecdsa_can_do,
336 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200337 ecdsa_sign_wrap,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200338 NULL,
339 NULL,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200340 ecdsa_alloc_wrap,
341 ecdsa_free_wrap,
342 eckey_debug, /* Compatible key structures */
343};
344#endif /* POLARSSL_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200345
346/*
347 * Support for alternative RSA-private implementations
348 */
349
350static size_t rsa_alt_get_size( const void *ctx )
351{
352 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
353
354 return( rsa_alt->key_len_func( rsa_alt->key ) );
355}
356
357static int rsa_alt_sign_wrap( void *ctx, md_type_t md_alg,
358 const unsigned char *hash, size_t hash_len,
359 unsigned char *sig, size_t *sig_len,
360 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
361{
362 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
363
364 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
365
366 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, RSA_PRIVATE,
367 md_alg, hash_len, hash, sig ) );
368}
369
370static int rsa_alt_decrypt_wrap( void *ctx,
371 const unsigned char *input, size_t ilen,
372 unsigned char *output, size_t *olen, size_t osize,
373 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
374{
375 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
376
377 ((void) f_rng);
378 ((void) p_rng);
379
380 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
381 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
382
383 return( rsa_alt->decrypt_func( rsa_alt->key,
384 RSA_PRIVATE, olen, input, output, osize ) );
385}
386
387static void *rsa_alt_alloc_wrap( void )
388{
389 void *ctx = polarssl_malloc( sizeof( rsa_alt_context ) );
390
391 if( ctx != NULL )
392 memset( ctx, 0, sizeof( rsa_alt_context ) );
393
394 return ctx;
395}
396
397static void rsa_alt_free_wrap( void *ctx )
398{
399 polarssl_free( ctx );
400}
401
402const pk_info_t rsa_alt_info = {
403 POLARSSL_PK_RSA_ALT,
404 "RSA-alt",
405 rsa_alt_get_size,
406 rsa_can_do,
407 NULL,
408 rsa_alt_sign_wrap,
409 rsa_alt_decrypt_wrap,
410 NULL,
411 rsa_alt_alloc_wrap,
412 rsa_alt_free_wrap,
413 NULL,
414};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200415
416#endif /* POLARSSL_PK_C */