PolarSSL v1.3.9
pk_wrap.c
Go to the documentation of this file.
1/*
2 * Public Key abstraction layer: wrapper functions
3 *
4 * Copyright (C) 2006-2014, 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#if !defined(POLARSSL_CONFIG_FILE)
27#include "polarssl/config.h"
28#else
29#include POLARSSL_CONFIG_FILE
30#endif
31
32#if defined(POLARSSL_PK_C)
33
34#include "polarssl/pk_wrap.h"
35
36/* Even if RSA not activated, for the sake of RSA-alt */
37#include "polarssl/rsa.h"
38
39#if defined(POLARSSL_ECP_C)
40#include "polarssl/ecp.h"
41#endif
42
43#if defined(POLARSSL_ECDSA_C)
44#include "polarssl/ecdsa.h"
45#endif
46
47#if defined(POLARSSL_PLATFORM_C)
48#include "polarssl/platform.h"
49#else
50#include <stdlib.h>
51#define polarssl_malloc malloc
52#define polarssl_free free
53#endif
54
55/* Implementation that should never be optimized out by the compiler */
56static void polarssl_zeroize( void *v, size_t n ) {
57 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
58}
59
60#if defined(POLARSSL_RSA_C)
61static int rsa_can_do( pk_type_t type )
62{
63 return( type == POLARSSL_PK_RSA ||
64 type == POLARSSL_PK_RSASSA_PSS );
65}
66
67static size_t rsa_get_size( const void *ctx )
68{
69 return( 8 * ((const rsa_context *) ctx)->len );
70}
71
72static int rsa_verify_wrap( void *ctx, md_type_t md_alg,
73 const unsigned char *hash, size_t hash_len,
74 const unsigned char *sig, size_t sig_len )
75{
76 int ret;
77
78 if( sig_len < ((rsa_context *) ctx)->len )
80
81 if( ( ret = rsa_pkcs1_verify( (rsa_context *) ctx, NULL, NULL,
82 RSA_PUBLIC, md_alg,
83 (unsigned int) hash_len, hash, sig ) ) != 0 )
84 return( ret );
85
86 if( sig_len > ((rsa_context *) ctx)->len )
88
89 return( 0 );
90}
91
92static int rsa_sign_wrap( void *ctx, md_type_t md_alg,
93 const unsigned char *hash, size_t hash_len,
94 unsigned char *sig, size_t *sig_len,
95 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
96{
97 *sig_len = ((rsa_context *) ctx)->len;
98
99 return( rsa_pkcs1_sign( (rsa_context *) ctx, f_rng, p_rng, RSA_PRIVATE,
100 md_alg, (unsigned int) hash_len, hash, sig ) );
101}
102
103static int rsa_decrypt_wrap( void *ctx,
104 const unsigned char *input, size_t ilen,
105 unsigned char *output, size_t *olen, size_t osize,
106 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
107{
108 if( ilen != ((rsa_context *) ctx)->len )
110
111 return( rsa_pkcs1_decrypt( (rsa_context *) ctx, f_rng, p_rng,
112 RSA_PRIVATE, olen, input, output, osize ) );
113}
114
115static int rsa_encrypt_wrap( void *ctx,
116 const unsigned char *input, size_t ilen,
117 unsigned char *output, size_t *olen, size_t osize,
118 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
119{
120 ((void) osize);
121
122 *olen = ((rsa_context *) ctx)->len;
123
124 return( rsa_pkcs1_encrypt( (rsa_context *) ctx,
125 f_rng, p_rng, RSA_PUBLIC, ilen, input, output ) );
126}
127
128static void *rsa_alloc_wrap( void )
129{
130 void *ctx = polarssl_malloc( sizeof( rsa_context ) );
131
132 if( ctx != NULL )
133 rsa_init( (rsa_context *) ctx, 0, 0 );
134
135 return( ctx );
136}
137
138static void rsa_free_wrap( void *ctx )
139{
140 rsa_free( (rsa_context *) ctx );
141 polarssl_free( ctx );
142}
143
144static void rsa_debug( const void *ctx, pk_debug_item *items )
145{
147 items->name = "rsa.N";
148 items->value = &( ((rsa_context *) ctx)->N );
149
150 items++;
151
153 items->name = "rsa.E";
154 items->value = &( ((rsa_context *) ctx)->E );
155}
156
157const pk_info_t rsa_info = {
159 "RSA",
160 rsa_get_size,
161 rsa_can_do,
162 rsa_verify_wrap,
163 rsa_sign_wrap,
164 rsa_decrypt_wrap,
165 rsa_encrypt_wrap,
166 rsa_alloc_wrap,
167 rsa_free_wrap,
168 rsa_debug,
169};
170#endif /* POLARSSL_RSA_C */
171
172#if defined(POLARSSL_ECP_C)
173/*
174 * Generic EC key
175 */
176static int eckey_can_do( pk_type_t type )
177{
178 return( type == POLARSSL_PK_ECKEY ||
179 type == POLARSSL_PK_ECKEY_DH ||
180 type == POLARSSL_PK_ECDSA );
181}
182
183static size_t eckey_get_size( const void *ctx )
184{
185 return( ((ecp_keypair *) ctx)->grp.pbits );
186}
187
188#if defined(POLARSSL_ECDSA_C)
189/* Forward declarations */
190static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg,
191 const unsigned char *hash, size_t hash_len,
192 const unsigned char *sig, size_t sig_len );
193
194static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg,
195 const unsigned char *hash, size_t hash_len,
196 unsigned char *sig, size_t *sig_len,
197 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
198
199static int eckey_verify_wrap( void *ctx, md_type_t md_alg,
200 const unsigned char *hash, size_t hash_len,
201 const unsigned char *sig, size_t sig_len )
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_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
210
211 ecdsa_free( &ecdsa );
212
213 return( ret );
214}
215
216static int eckey_sign_wrap( void *ctx, md_type_t md_alg,
217 const unsigned char *hash, size_t hash_len,
218 unsigned char *sig, size_t *sig_len,
219 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
220{
221 int ret;
222 ecdsa_context ecdsa;
223
224 ecdsa_init( &ecdsa );
225
226 if( ( ret = ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
227 ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
228 f_rng, p_rng );
229
230 ecdsa_free( &ecdsa );
231
232 return( ret );
233}
234
235#endif /* POLARSSL_ECDSA_C */
236
237static void *eckey_alloc_wrap( void )
238{
239 void *ctx = polarssl_malloc( sizeof( ecp_keypair ) );
240
241 if( ctx != NULL )
242 ecp_keypair_init( ctx );
243
244 return( ctx );
245}
246
247static void eckey_free_wrap( void *ctx )
248{
249 ecp_keypair_free( (ecp_keypair *) ctx );
250 polarssl_free( ctx );
251}
252
253static void eckey_debug( const void *ctx, pk_debug_item *items )
254{
256 items->name = "eckey.Q";
257 items->value = &( ((ecp_keypair *) ctx)->Q );
258}
259
260const pk_info_t eckey_info = {
262 "EC",
263 eckey_get_size,
264 eckey_can_do,
265#if defined(POLARSSL_ECDSA_C)
266 eckey_verify_wrap,
267 eckey_sign_wrap,
268#else
269 NULL,
270 NULL,
271#endif
272 NULL,
273 NULL,
274 eckey_alloc_wrap,
275 eckey_free_wrap,
276 eckey_debug,
277};
278
279/*
280 * EC key restricted to ECDH
281 */
282static int eckeydh_can_do( pk_type_t type )
283{
284 return( type == POLARSSL_PK_ECKEY ||
285 type == POLARSSL_PK_ECKEY_DH );
286}
287
288const pk_info_t eckeydh_info = {
290 "EC_DH",
291 eckey_get_size, /* Same underlying key structure */
292 eckeydh_can_do,
293 NULL,
294 NULL,
295 NULL,
296 NULL,
297 eckey_alloc_wrap, /* Same underlying key structure */
298 eckey_free_wrap, /* Same underlying key structure */
299 eckey_debug, /* Same underlying key structure */
300};
301#endif /* POLARSSL_ECP_C */
302
303#if defined(POLARSSL_ECDSA_C)
304static int ecdsa_can_do( pk_type_t type )
305{
306 return( type == POLARSSL_PK_ECDSA );
307}
308
309static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg,
310 const unsigned char *hash, size_t hash_len,
311 const unsigned char *sig, size_t sig_len )
312{
313 int ret;
314 ((void) md_alg);
315
316 ret = ecdsa_read_signature( (ecdsa_context *) ctx,
317 hash, hash_len, sig, sig_len );
318
321
322 return( ret );
323}
324
325static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg,
326 const unsigned char *hash, size_t hash_len,
327 unsigned char *sig, size_t *sig_len,
328 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
329{
330 /* Use deterministic ECDSA by default if available */
331#if defined(POLARSSL_ECDSA_DETERMINISTIC)
332 ((void) f_rng);
333 ((void) p_rng);
334
336 hash, hash_len, sig, sig_len, md_alg ) );
337#else
338 ((void) md_alg);
339
340 return( ecdsa_write_signature( (ecdsa_context *) ctx,
341 hash, hash_len, sig, sig_len, f_rng, p_rng ) );
342#endif /* POLARSSL_ECDSA_DETERMINISTIC */
343}
344
345static void *ecdsa_alloc_wrap( void )
346{
347 void *ctx = polarssl_malloc( sizeof( ecdsa_context ) );
348
349 if( ctx != NULL )
350 ecdsa_init( (ecdsa_context *) ctx );
351
352 return( ctx );
353}
354
355static void ecdsa_free_wrap( void *ctx )
356{
357 ecdsa_free( (ecdsa_context *) ctx );
358 polarssl_free( ctx );
359}
360
361const pk_info_t ecdsa_info = {
363 "ECDSA",
364 eckey_get_size, /* Compatible key structures */
365 ecdsa_can_do,
366 ecdsa_verify_wrap,
367 ecdsa_sign_wrap,
368 NULL,
369 NULL,
370 ecdsa_alloc_wrap,
371 ecdsa_free_wrap,
372 eckey_debug, /* Compatible key structures */
373};
374#endif /* POLARSSL_ECDSA_C */
375
376/*
377 * Support for alternative RSA-private implementations
378 */
379
380static int rsa_alt_can_do( pk_type_t type )
381{
382 return( type == POLARSSL_PK_RSA );
383}
384
385static size_t rsa_alt_get_size( const void *ctx )
386{
387 const rsa_alt_context *rsa_alt = (const rsa_alt_context *) ctx;
388
389 return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
390}
391
392static int rsa_alt_sign_wrap( void *ctx, md_type_t md_alg,
393 const unsigned char *hash, size_t hash_len,
394 unsigned char *sig, size_t *sig_len,
395 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
396{
397 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
398
399 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
400
401 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, RSA_PRIVATE,
402 md_alg, (unsigned int) hash_len, hash, sig ) );
403}
404
405static int rsa_alt_decrypt_wrap( void *ctx,
406 const unsigned char *input, size_t ilen,
407 unsigned char *output, size_t *olen, size_t osize,
408 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
409{
410 rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx;
411
412 ((void) f_rng);
413 ((void) p_rng);
414
415 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
417
418 return( rsa_alt->decrypt_func( rsa_alt->key,
419 RSA_PRIVATE, olen, input, output, osize ) );
420}
421
422static void *rsa_alt_alloc_wrap( void )
423{
424 void *ctx = polarssl_malloc( sizeof( rsa_alt_context ) );
425
426 if( ctx != NULL )
427 memset( ctx, 0, sizeof( rsa_alt_context ) );
428
429 return( ctx );
430}
431
432static void rsa_alt_free_wrap( void *ctx )
433{
434 polarssl_zeroize( ctx, sizeof( rsa_alt_context ) );
435 polarssl_free( ctx );
436}
437
438const pk_info_t rsa_alt_info = {
440 "RSA-alt",
441 rsa_alt_get_size,
442 rsa_alt_can_do,
443 NULL,
444 rsa_alt_sign_wrap,
445 rsa_alt_decrypt_wrap,
446 NULL,
447 rsa_alt_alloc_wrap,
448 rsa_alt_free_wrap,
449 NULL,
450};
451
452#endif /* POLARSSL_PK_C */
Configuration options (set of defines)
Elliptic curve DSA.
int ecdsa_from_keypair(ecdsa_context *ctx, const ecp_keypair *key)
Set an ECDSA context from an EC key pair.
int ecdsa_read_signature(ecdsa_context *ctx, const unsigned char *hash, size_t hlen, const unsigned char *sig, size_t slen)
Read and verify an ECDSA signature.
void ecdsa_init(ecdsa_context *ctx)
Initialize context.
int ecdsa_write_signature(ecdsa_context *ctx, const unsigned char *hash, size_t hlen, unsigned char *sig, size_t *slen, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Compute ECDSA signature and write it to buffer, serialized as defined in RFC 4492 page 20.
void ecdsa_free(ecdsa_context *ctx)
Free context.
int ecdsa_write_signature_det(ecdsa_context *ctx, const unsigned char *hash, size_t hlen, unsigned char *sig, size_t *slen, md_type_t md_alg)
Compute ECDSA signature and write it to buffer, serialized as defined in RFC 4492 page 20.
Elliptic curves over GF(p)
#define POLARSSL_ERR_ECP_SIG_LEN_MISMATCH
Signature is valid but shorter than the user-supplied length.
Definition: ecp.h:42
void ecp_keypair_free(ecp_keypair *key)
Free the components of a key pair.
void ecp_keypair_init(ecp_keypair *key)
Initialize a key pair (as an invalid one)
md_type_t
Definition: md.h:51
#define POLARSSL_ERR_PK_SIG_LEN_MISMATCH
The signature is valid but its length is less than expected.
Definition: pk.h:64
@ POLARSSL_PK_DEBUG_MPI
Definition: pk.h:122
@ POLARSSL_PK_DEBUG_ECP
Definition: pk.h:123
pk_type_t
Public key types.
Definition: pk.h:95
@ POLARSSL_PK_ECDSA
Definition: pk.h:100
@ POLARSSL_PK_ECKEY
Definition: pk.h:98
@ POLARSSL_PK_ECKEY_DH
Definition: pk.h:99
@ POLARSSL_PK_RSASSA_PSS
Definition: pk.h:102
@ POLARSSL_PK_RSA_ALT
Definition: pk.h:101
@ POLARSSL_PK_RSA
Definition: pk.h:97
const pk_info_t rsa_alt_info
const pk_info_t eckey_info
const pk_info_t ecdsa_info
const pk_info_t rsa_info
const pk_info_t eckeydh_info
PolarSSL Platform abstraction layer.
The RSA public-key cryptosystem.
int rsa_pkcs1_decrypt(rsa_context *ctx, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, size_t *olen, const unsigned char *input, unsigned char *output, size_t output_max_len)
Generic wrapper to perform a PKCS#1 decryption using the mode from the context.
int rsa_pkcs1_encrypt(rsa_context *ctx, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, size_t ilen, const unsigned char *input, unsigned char *output)
Generic wrapper to perform a PKCS#1 encryption using the mode from the context.
int rsa_pkcs1_sign(rsa_context *ctx, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig)
Generic wrapper to perform a PKCS#1 signature using the mode from the context.
#define RSA_PUBLIC
Definition: rsa.h:59
#define POLARSSL_ERR_RSA_VERIFY_FAILED
The PKCS#1 verification failed.
Definition: rsa.h:52
int rsa_pkcs1_verify(rsa_context *ctx, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, const unsigned char *sig)
Generic wrapper to perform a PKCS#1 verification using the mode from the context.
void rsa_init(rsa_context *ctx, int padding, int hash_id)
Initialize an RSA context.
#define POLARSSL_ERR_RSA_BAD_INPUT_DATA
Bad input parameters to function.
Definition: rsa.h:46
void rsa_free(rsa_context *ctx)
Free the components of an RSA key.
#define RSA_PRIVATE
Definition: rsa.h:60
ECDSA context structure.
Definition: ecdsa.h:42
ECP key pair structure.
Definition: ecp.h:164
Item to send to the debug module.
Definition: pk.h:130
pk_debug_type type
Definition: pk.h:131
void * value
Definition: pk.h:133
const char * name
Definition: pk.h:132
Public key information and operations.
Definition: pk.h:143
pk_rsa_alt_decrypt_func decrypt_func
Definition: pk_wrap.h:43
pk_rsa_alt_key_len_func key_len_func
Definition: pk_wrap.h:45
pk_rsa_alt_sign_func sign_func
Definition: pk_wrap.h:44
void * key
Definition: pk_wrap.h:42
RSA context structure.
Definition: rsa.h:84
#define polarssl_malloc
#define polarssl_free