PolarSSL v1.3.9
pk.c
Go to the documentation of this file.
1 /*
2  * Public Key abstraction layer
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.h"
35 #include "polarssl/pk_wrap.h"
36 
37 #if defined(POLARSSL_RSA_C)
38 #include "polarssl/rsa.h"
39 #endif
40 #if defined(POLARSSL_ECP_C)
41 #include "polarssl/ecp.h"
42 #endif
43 #if defined(POLARSSL_ECDSA_C)
44 #include "polarssl/ecdsa.h"
45 #endif
46 
47 /* Implementation that should never be optimized out by the compiler */
48 static void polarssl_zeroize( void *v, size_t n ) {
49  volatile unsigned char *p = v; while( n-- ) *p++ = 0;
50 }
51 
52 /*
53  * Initialise a pk_context
54  */
55 void pk_init( pk_context *ctx )
56 {
57  if( ctx == NULL )
58  return;
59 
60  ctx->pk_info = NULL;
61  ctx->pk_ctx = NULL;
62 }
63 
64 /*
65  * Free (the components of) a pk_context
66  */
67 void pk_free( pk_context *ctx )
68 {
69  if( ctx == NULL || ctx->pk_info == NULL )
70  return;
71 
72  ctx->pk_info->ctx_free_func( ctx->pk_ctx );
73 
74  polarssl_zeroize( ctx, sizeof( pk_context ) );
75 }
76 
77 /*
78  * Get pk_info structure from type
79  */
80 const pk_info_t * pk_info_from_type( pk_type_t pk_type )
81 {
82  switch( pk_type ) {
83 #if defined(POLARSSL_RSA_C)
84  case POLARSSL_PK_RSA:
85  return( &rsa_info );
86 #endif
87 #if defined(POLARSSL_ECP_C)
88  case POLARSSL_PK_ECKEY:
89  return( &eckey_info );
91  return( &eckeydh_info );
92 #endif
93 #if defined(POLARSSL_ECDSA_C)
94  case POLARSSL_PK_ECDSA:
95  return( &ecdsa_info );
96 #endif
97  /* POLARSSL_PK_RSA_ALT omitted on purpose */
98  default:
99  return( NULL );
100  }
101 }
102 
103 /*
104  * Initialise context
105  */
106 int pk_init_ctx( pk_context *ctx, const pk_info_t *info )
107 {
108  if( ctx == NULL || info == NULL || ctx->pk_info != NULL )
110 
111  if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
113 
114  ctx->pk_info = info;
115 
116  return( 0 );
117 }
118 
119 /*
120  * Initialize an RSA-alt context
121  */
122 int pk_init_ctx_rsa_alt( pk_context *ctx, void * key,
123  pk_rsa_alt_decrypt_func decrypt_func,
124  pk_rsa_alt_sign_func sign_func,
125  pk_rsa_alt_key_len_func key_len_func )
126 {
127  rsa_alt_context *rsa_alt;
128  const pk_info_t *info = &rsa_alt_info;
129 
130  if( ctx == NULL || ctx->pk_info != NULL )
132 
133  if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
135 
136  ctx->pk_info = info;
137 
138  rsa_alt = (rsa_alt_context *) ctx->pk_ctx;
139 
140  rsa_alt->key = key;
141  rsa_alt->decrypt_func = decrypt_func;
142  rsa_alt->sign_func = sign_func;
143  rsa_alt->key_len_func = key_len_func;
144 
145  return( 0 );
146 }
147 
148 /*
149  * Tell if a PK can do the operations of the given type
150  */
151 int pk_can_do( pk_context *ctx, pk_type_t type )
152 {
153  /* null or NONE context can't do anything */
154  if( ctx == NULL || ctx->pk_info == NULL )
155  return( 0 );
156 
157  return( ctx->pk_info->can_do( type ) );
158 }
159 
160 /*
161  * Helper for pk_sign and pk_verify
162  */
163 static inline int pk_hashlen_helper( md_type_t md_alg, size_t *hash_len )
164 {
165  const md_info_t *md_info;
166 
167  if( *hash_len != 0 )
168  return( 0 );
169 
170  if( ( md_info = md_info_from_type( md_alg ) ) == NULL )
171  return( -1 );
172 
173  *hash_len = md_info->size;
174  return( 0 );
175 }
176 
177 /*
178  * Verify a signature
179  */
180 int pk_verify( pk_context *ctx, md_type_t md_alg,
181  const unsigned char *hash, size_t hash_len,
182  const unsigned char *sig, size_t sig_len )
183 {
184  if( ctx == NULL || ctx->pk_info == NULL ||
185  pk_hashlen_helper( md_alg, &hash_len ) != 0 )
187 
188  if( ctx->pk_info->verify_func == NULL )
190 
191  return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
192  sig, sig_len ) );
193 }
194 
195 /*
196  * Verify a signature with options
197  */
198 int pk_verify_ext( pk_type_t type, const void *options,
199  pk_context *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  if( ctx == NULL || ctx->pk_info == NULL )
205 
206  if( ! pk_can_do( ctx, type ) )
208 
209  if( type == POLARSSL_PK_RSASSA_PSS )
210  {
211 #if defined(POLARSSL_RSA_C) && defined(POLARSSL_PKCS1_V21)
212  int ret;
213  const pk_rsassa_pss_options *pss_opts;
214 
215  if( options == NULL )
217 
218  pss_opts = (const pk_rsassa_pss_options *) options;
219 
220  if( sig_len < pk_get_len( ctx ) )
222 
223  ret = rsa_rsassa_pss_verify_ext( pk_rsa( *ctx ),
224  NULL, NULL, RSA_PUBLIC,
225  md_alg, (unsigned int) hash_len, hash,
226  pss_opts->mgf1_hash_id,
227  pss_opts->expected_salt_len,
228  sig );
229  if( ret != 0 )
230  return( ret );
231 
232  if( sig_len > pk_get_len( ctx ) )
234 
235  return( 0 );
236 #else
238 #endif
239  }
240 
241  /* General case: no options */
242  if( options != NULL )
244 
245  return( pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
246 }
247 
248 /*
249  * Make a signature
250  */
251 int pk_sign( pk_context *ctx, md_type_t md_alg,
252  const unsigned char *hash, size_t hash_len,
253  unsigned char *sig, size_t *sig_len,
254  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
255 {
256  if( ctx == NULL || ctx->pk_info == NULL ||
257  pk_hashlen_helper( md_alg, &hash_len ) != 0 )
259 
260  if( ctx->pk_info->sign_func == NULL )
262 
263  return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
264  sig, sig_len, f_rng, p_rng ) );
265 }
266 
267 /*
268  * Decrypt message
269  */
270 int pk_decrypt( pk_context *ctx,
271  const unsigned char *input, size_t ilen,
272  unsigned char *output, size_t *olen, size_t osize,
273  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
274 {
275  if( ctx == NULL || ctx->pk_info == NULL )
277 
278  if( ctx->pk_info->decrypt_func == NULL )
280 
281  return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
282  output, olen, osize, f_rng, p_rng ) );
283 }
284 
285 /*
286  * Encrypt message
287  */
288 int pk_encrypt( pk_context *ctx,
289  const unsigned char *input, size_t ilen,
290  unsigned char *output, size_t *olen, size_t osize,
291  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
292 {
293  if( ctx == NULL || ctx->pk_info == NULL )
295 
296  if( ctx->pk_info->encrypt_func == NULL )
298 
299  return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
300  output, olen, osize, f_rng, p_rng ) );
301 }
302 
303 /*
304  * Get key size in bits
305  */
306 size_t pk_get_size( const pk_context *ctx )
307 {
308  if( ctx == NULL || ctx->pk_info == NULL )
309  return( 0 );
310 
311  return( ctx->pk_info->get_size( ctx->pk_ctx ) );
312 }
313 
314 /*
315  * Export debug information
316  */
317 int pk_debug( const pk_context *ctx, pk_debug_item *items )
318 {
319  if( ctx == NULL || ctx->pk_info == NULL )
321 
322  if( ctx->pk_info->debug_func == NULL )
324 
325  ctx->pk_info->debug_func( ctx->pk_ctx, items );
326  return( 0 );
327 }
328 
329 /*
330  * Access the PK type name
331  */
332 const char * pk_get_name( const pk_context *ctx )
333 {
334  if( ctx == NULL || ctx->pk_info == NULL )
335  return( "invalid PK" );
336 
337  return( ctx->pk_info->name );
338 }
339 
340 /*
341  * Access the PK type
342  */
343 pk_type_t pk_get_type( const pk_context *ctx )
344 {
345  if( ctx == NULL || ctx->pk_info == NULL )
346  return( POLARSSL_PK_NONE );
347 
348  return( ctx->pk_info->type );
349 }
350 
351 #endif /* POLARSSL_PK_C */
size_t(* pk_rsa_alt_key_len_func)(void *ctx)
Definition: pk.h:210
static size_t pk_get_len(const pk_context *ctx)
Get the length in bytes of the underlying key.
Definition: pk.h:281
#define POLARSSL_ERR_PK_SIG_LEN_MISMATCH
The signature is valid but its length is less than expected.
Definition: pk.h:64
const pk_info_t * pk_info_from_type(pk_type_t pk_type)
Return information associated with the given PK type.
pk_rsa_alt_decrypt_func decrypt_func
Definition: pk_wrap.h:43
const pk_info_t eckeydh_info
Elliptic curves over GF(p)
size_t pk_get_size(const pk_context *ctx)
Get the size in bits of the underlying key.
int(* sign_func)(void *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t *sig_len, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Make signature.
Definition: pk.h:162
Elliptic curve DSA.
Options for RSASSA-PSS signature verification.
Definition: pk.h:109
#define RSA_PUBLIC
Definition: rsa.h:59
int pk_decrypt(pk_context *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, size_t osize, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Decrypt message (including padding if relevant).
int pk_debug(const pk_context *ctx, pk_debug_item *items)
Export debug information.
Configuration options (set of defines)
void(* ctx_free_func)(void *ctx)
Free the given context.
Definition: pk.h:184
const pk_info_t * pk_info
Public key informations.
Definition: pk.h:196
pk_type_t pk_get_type(const pk_context *ctx)
Get the key type.
const char * pk_get_name(const pk_context *ctx)
Access the type name.
int expected_salt_len
Definition: pk.h:112
Public Key abstraction layer.
int pk_init_ctx_rsa_alt(pk_context *ctx, void *key, pk_rsa_alt_decrypt_func decrypt_func, pk_rsa_alt_sign_func sign_func, pk_rsa_alt_key_len_func key_len_func)
Initialize an RSA-alt context.
#define POLARSSL_ERR_PK_BAD_INPUT_DATA
Bad input parameters to function.
Definition: pk.h:53
int pk_verify_ext(pk_type_t type, const void *options, pk_context *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len)
Verify signature, with options.
md_type_t
Definition: md.h:51
#define POLARSSL_ERR_PK_FEATURE_UNAVAILABLE
Unavailable feature, e.g.
Definition: pk.h:63
int rsa_rsassa_pss_verify_ext(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, md_type_t mgf1_hash_id, int expected_salt_len, const unsigned char *sig)
Perform a PKCS#1 v2.1 PSS verification (RSASSA-PSS-VERIFY) (This is the version with "full" options...
const md_info_t * md_info_from_type(md_type_t md_type)
Returns the message digest information associated with the given digest type.
md_type_t mgf1_hash_id
Definition: pk.h:111
Item to send to the debug module.
Definition: pk.h:129
int pk_verify(pk_context *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len)
Verify signature (including padding if relevant).
int(* pk_rsa_alt_decrypt_func)(void *ctx, int mode, size_t *olen, const unsigned char *input, unsigned char *output, size_t output_max_len)
Types for RSA-alt abstraction.
Definition: pk.h:203
Public key information and operations.
Definition: pk.h:142
int pk_can_do(pk_context *ctx, pk_type_t type)
Tell if a context can do the operation given by type.
#define POLARSSL_ERR_PK_MALLOC_FAILED
Memory alloation failed.
Definition: pk.h:51
int(* can_do)(pk_type_t type)
Tell if the context implements this type (e.g.
Definition: pk.h:154
void * pk_ctx
Underlying public key context.
Definition: pk.h:197
pk_type_t
Public key types.
Definition: pk.h:95
int(* pk_rsa_alt_sign_func)(void *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)
Definition: pk.h:206
int(* encrypt_func)(void *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, size_t osize, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Encrypt message.
Definition: pk.h:175
#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 pk_init_ctx(pk_context *ctx, const pk_info_t *info)
Initialize a PK context with the information given and allocates the type-specific PK subcontext...
const pk_info_t rsa_alt_info
size_t(* get_size)(const void *)
Get key size in bits.
Definition: pk.h:151
The RSA public-key cryptosystem.
#define POLARSSL_ERR_PK_TYPE_MISMATCH
Type mismatch, eg attempt to encrypt with an ECDSA key.
Definition: pk.h:52
void pk_free(pk_context *ctx)
Free a pk_context.
int pk_sign(pk_context *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t *sig_len, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Make signature, including padding if relevant.
const pk_info_t eckey_info
const pk_info_t rsa_info
const pk_info_t ecdsa_info
int pk_encrypt(pk_context *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, size_t osize, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Encrypt message (including padding if relevant).
void pk_init(pk_context *ctx)
Initialize a pk_context (as NONE)
int(* decrypt_func)(void *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, size_t osize, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Decrypt message.
Definition: pk.h:169
int size
Output length of the digest function.
Definition: md.h:82
const char * name
Type name.
Definition: pk.h:148
pk_rsa_alt_key_len_func key_len_func
Definition: pk_wrap.h:45
void * key
Definition: pk_wrap.h:42
pk_type_t type
Public key type.
Definition: pk.h:145
int(* verify_func)(void *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len)
Verify signature.
Definition: pk.h:157
Message digest information.
Definition: md.h:74
void *(* ctx_alloc_func)(void)
Allocate a new context.
Definition: pk.h:181
Public key container.
Definition: pk.h:194
void(* debug_func)(const void *ctx, pk_debug_item *items)
Interface with the debug module.
Definition: pk.h:187
#define pk_rsa(pk)
Quick access to an RSA context inside a PK context.
Definition: pk.h:74