mbed TLS library
Dependents: HTTPClient-SSL WS_SERVER
pk.c
00001 /* 00002 * Public Key abstraction layer 00003 * 00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved 00005 * 00006 * This file is part of mbed TLS (https://tls.mbed.org) 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License along 00019 * with this program; if not, write to the Free Software Foundation, Inc., 00020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 */ 00022 00023 #if !defined(POLARSSL_CONFIG_FILE) 00024 #include "polarssl/config.h" 00025 #else 00026 #include POLARSSL_CONFIG_FILE 00027 #endif 00028 00029 #if defined(POLARSSL_PK_C) 00030 #include "polarssl/pk.h" 00031 #include "polarssl/pk_wrap.h" 00032 00033 #if defined(POLARSSL_RSA_C) 00034 #include "polarssl/rsa.h" 00035 #endif 00036 #if defined(POLARSSL_ECP_C) 00037 #include "polarssl/ecp.h" 00038 #endif 00039 #if defined(POLARSSL_ECDSA_C) 00040 #include "polarssl/ecdsa.h" 00041 #endif 00042 00043 /* Implementation that should never be optimized out by the compiler */ 00044 static void polarssl_zeroize( void *v, size_t n ) { 00045 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00046 } 00047 00048 /* 00049 * Initialise a pk_context 00050 */ 00051 void pk_init( pk_context *ctx ) 00052 { 00053 if( ctx == NULL ) 00054 return; 00055 00056 ctx->pk_info = NULL; 00057 ctx->pk_ctx = NULL; 00058 } 00059 00060 /* 00061 * Free (the components of) a pk_context 00062 */ 00063 void pk_free( pk_context *ctx ) 00064 { 00065 if( ctx == NULL || ctx->pk_info == NULL ) 00066 return; 00067 00068 ctx->pk_info->ctx_free_func( ctx->pk_ctx ); 00069 00070 polarssl_zeroize( ctx, sizeof( pk_context ) ); 00071 } 00072 00073 /* 00074 * Get pk_info structure from type 00075 */ 00076 const pk_info_t * pk_info_from_type( pk_type_t pk_type ) 00077 { 00078 switch( pk_type ) { 00079 #if defined(POLARSSL_RSA_C) 00080 case POLARSSL_PK_RSA: 00081 return( &rsa_info ); 00082 #endif 00083 #if defined(POLARSSL_ECP_C) 00084 case POLARSSL_PK_ECKEY: 00085 return( &eckey_info ); 00086 case POLARSSL_PK_ECKEY_DH: 00087 return( &eckeydh_info ); 00088 #endif 00089 #if defined(POLARSSL_ECDSA_C) 00090 case POLARSSL_PK_ECDSA: 00091 return( &ecdsa_info ); 00092 #endif 00093 /* POLARSSL_PK_RSA_ALT omitted on purpose */ 00094 default: 00095 return( NULL ); 00096 } 00097 } 00098 00099 /* 00100 * Initialise context 00101 */ 00102 int pk_init_ctx( pk_context *ctx, const pk_info_t *info ) 00103 { 00104 if( ctx == NULL || info == NULL || ctx->pk_info != NULL ) 00105 return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); 00106 00107 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) 00108 return( POLARSSL_ERR_PK_MALLOC_FAILED ); 00109 00110 ctx->pk_info = info; 00111 00112 return( 0 ); 00113 } 00114 00115 /* 00116 * Initialize an RSA-alt context 00117 */ 00118 int pk_init_ctx_rsa_alt( pk_context *ctx, void * key, 00119 pk_rsa_alt_decrypt_func decrypt_func, 00120 pk_rsa_alt_sign_func sign_func, 00121 pk_rsa_alt_key_len_func key_len_func ) 00122 { 00123 rsa_alt_context *rsa_alt; 00124 const pk_info_t *info = &rsa_alt_info; 00125 00126 if( ctx == NULL || ctx->pk_info != NULL ) 00127 return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); 00128 00129 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) 00130 return( POLARSSL_ERR_PK_MALLOC_FAILED ); 00131 00132 ctx->pk_info = info; 00133 00134 rsa_alt = (rsa_alt_context *) ctx->pk_ctx; 00135 00136 rsa_alt->key = key; 00137 rsa_alt->decrypt_func = decrypt_func; 00138 rsa_alt->sign_func = sign_func; 00139 rsa_alt->key_len_func = key_len_func; 00140 00141 return( 0 ); 00142 } 00143 00144 /* 00145 * Tell if a PK can do the operations of the given type 00146 */ 00147 int pk_can_do( pk_context *ctx, pk_type_t type ) 00148 { 00149 /* null or NONE context can't do anything */ 00150 if( ctx == NULL || ctx->pk_info == NULL ) 00151 return( 0 ); 00152 00153 return( ctx->pk_info->can_do( type ) ); 00154 } 00155 00156 /* 00157 * Helper for pk_sign and pk_verify 00158 */ 00159 static inline int pk_hashlen_helper( md_type_t md_alg, size_t *hash_len ) 00160 { 00161 const md_info_t *md_info; 00162 00163 if( *hash_len != 0 ) 00164 return( 0 ); 00165 00166 if( ( md_info = md_info_from_type( md_alg ) ) == NULL ) 00167 return( -1 ); 00168 00169 *hash_len = md_info->size; 00170 return( 0 ); 00171 } 00172 00173 /* 00174 * Verify a signature 00175 */ 00176 int pk_verify( pk_context *ctx, md_type_t md_alg, 00177 const unsigned char *hash, size_t hash_len, 00178 const unsigned char *sig, size_t sig_len ) 00179 { 00180 if( ctx == NULL || ctx->pk_info == NULL || 00181 pk_hashlen_helper( md_alg, &hash_len ) != 0 ) 00182 return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); 00183 00184 if( ctx->pk_info->verify_func == NULL ) 00185 return( POLARSSL_ERR_PK_TYPE_MISMATCH ); 00186 00187 return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len, 00188 sig, sig_len ) ); 00189 } 00190 00191 /* 00192 * Verify a signature with options 00193 */ 00194 int pk_verify_ext( pk_type_t type, const void *options, 00195 pk_context *ctx, md_type_t md_alg, 00196 const unsigned char *hash, size_t hash_len, 00197 const unsigned char *sig, size_t sig_len ) 00198 { 00199 if( ctx == NULL || ctx->pk_info == NULL ) 00200 return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); 00201 00202 if( ! pk_can_do( ctx, type ) ) 00203 return( POLARSSL_ERR_PK_TYPE_MISMATCH ); 00204 00205 if( type == POLARSSL_PK_RSASSA_PSS ) 00206 { 00207 #if defined(POLARSSL_RSA_C) && defined(POLARSSL_PKCS1_V21) 00208 int ret; 00209 const pk_rsassa_pss_options *pss_opts; 00210 00211 if( options == NULL ) 00212 return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); 00213 00214 pss_opts = (const pk_rsassa_pss_options *) options; 00215 00216 if( sig_len < pk_get_len( ctx ) ) 00217 return( POLARSSL_ERR_RSA_VERIFY_FAILED ); 00218 00219 ret = rsa_rsassa_pss_verify_ext( pk_rsa( *ctx ), 00220 NULL, NULL, RSA_PUBLIC, 00221 md_alg, (unsigned int) hash_len, hash, 00222 pss_opts->mgf1_hash_id, 00223 pss_opts->expected_salt_len, 00224 sig ); 00225 if( ret != 0 ) 00226 return( ret ); 00227 00228 if( sig_len > pk_get_len( ctx ) ) 00229 return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); 00230 00231 return( 0 ); 00232 #else 00233 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); 00234 #endif 00235 } 00236 00237 /* General case: no options */ 00238 if( options != NULL ) 00239 return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); 00240 00241 return( pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) ); 00242 } 00243 00244 /* 00245 * Make a signature 00246 */ 00247 int pk_sign( pk_context *ctx, md_type_t md_alg, 00248 const unsigned char *hash, size_t hash_len, 00249 unsigned char *sig, size_t *sig_len, 00250 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 00251 { 00252 if( ctx == NULL || ctx->pk_info == NULL || 00253 pk_hashlen_helper( md_alg, &hash_len ) != 0 ) 00254 return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); 00255 00256 if( ctx->pk_info->sign_func == NULL ) 00257 return( POLARSSL_ERR_PK_TYPE_MISMATCH ); 00258 00259 return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len, 00260 sig, sig_len, f_rng, p_rng ) ); 00261 } 00262 00263 /* 00264 * Decrypt message 00265 */ 00266 int pk_decrypt( pk_context *ctx, 00267 const unsigned char *input, size_t ilen, 00268 unsigned char *output, size_t *olen, size_t osize, 00269 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 00270 { 00271 if( ctx == NULL || ctx->pk_info == NULL ) 00272 return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); 00273 00274 if( ctx->pk_info->decrypt_func == NULL ) 00275 return( POLARSSL_ERR_PK_TYPE_MISMATCH ); 00276 00277 return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen, 00278 output, olen, osize, f_rng, p_rng ) ); 00279 } 00280 00281 /* 00282 * Encrypt message 00283 */ 00284 int pk_encrypt( pk_context *ctx, 00285 const unsigned char *input, size_t ilen, 00286 unsigned char *output, size_t *olen, size_t osize, 00287 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 00288 { 00289 if( ctx == NULL || ctx->pk_info == NULL ) 00290 return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); 00291 00292 if( ctx->pk_info->encrypt_func == NULL ) 00293 return( POLARSSL_ERR_PK_TYPE_MISMATCH ); 00294 00295 return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen, 00296 output, olen, osize, f_rng, p_rng ) ); 00297 } 00298 00299 /* 00300 * Check public-private key pair 00301 */ 00302 int pk_check_pair( const pk_context *pub, const pk_context *prv ) 00303 { 00304 if( pub == NULL || pub->pk_info == NULL || 00305 prv == NULL || prv->pk_info == NULL || 00306 prv->pk_info->check_pair_func == NULL ) 00307 { 00308 return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); 00309 } 00310 00311 if( prv->pk_info->type == POLARSSL_PK_RSA_ALT ) 00312 { 00313 if( pub->pk_info->type != POLARSSL_PK_RSA ) 00314 return( POLARSSL_ERR_PK_TYPE_MISMATCH ); 00315 } 00316 else 00317 { 00318 if( pub->pk_info != prv->pk_info ) 00319 return( POLARSSL_ERR_PK_TYPE_MISMATCH ); 00320 } 00321 00322 return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) ); 00323 } 00324 00325 /* 00326 * Get key size in bits 00327 */ 00328 size_t pk_get_size( const pk_context *ctx ) 00329 { 00330 if( ctx == NULL || ctx->pk_info == NULL ) 00331 return( 0 ); 00332 00333 return( ctx->pk_info->get_size( ctx->pk_ctx ) ); 00334 } 00335 00336 /* 00337 * Export debug information 00338 */ 00339 int pk_debug( const pk_context *ctx, pk_debug_item *items ) 00340 { 00341 if( ctx == NULL || ctx->pk_info == NULL ) 00342 return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); 00343 00344 if( ctx->pk_info->debug_func == NULL ) 00345 return( POLARSSL_ERR_PK_TYPE_MISMATCH ); 00346 00347 ctx->pk_info->debug_func( ctx->pk_ctx, items ); 00348 return( 0 ); 00349 } 00350 00351 /* 00352 * Access the PK type name 00353 */ 00354 const char * pk_get_name( const pk_context *ctx ) 00355 { 00356 if( ctx == NULL || ctx->pk_info == NULL ) 00357 return( "invalid PK" ); 00358 00359 return( ctx->pk_info->name ); 00360 } 00361 00362 /* 00363 * Access the PK type 00364 */ 00365 pk_type_t pk_get_type( const pk_context *ctx ) 00366 { 00367 if( ctx == NULL || ctx->pk_info == NULL ) 00368 return( POLARSSL_PK_NONE ); 00369 00370 return( ctx->pk_info->type ); 00371 } 00372 00373 #endif /* POLARSSL_PK_C */ 00374
Generated on Tue Jul 12 2022 13:50:37 by 1.7.2