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