Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pk.c Source File

pk.c

00001 /*
00002  *  Public Key abstraction layer
00003  *
00004  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
00005  *  SPDX-License-Identifier: Apache-2.0
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  *  This file is part of mbed TLS (https://tls.mbed.org)
00020  */
00021 
00022 #if !defined(MBEDTLS_CONFIG_FILE)
00023 #include "mbedtls/config.h"
00024 #else
00025 #include MBEDTLS_CONFIG_FILE
00026 #endif
00027 
00028 #if defined(MBEDTLS_PK_C)
00029 #include "mbedtls/pk.h"
00030 #include "mbedtls/pk_internal.h"
00031 
00032 #include "mbedtls/bignum.h"
00033 
00034 #if defined(MBEDTLS_RSA_C)
00035 #include "mbedtls/rsa.h"
00036 #endif
00037 #if defined(MBEDTLS_ECP_C)
00038 #include "mbedtls/ecp.h"
00039 #endif
00040 #if defined(MBEDTLS_ECDSA_C)
00041 #include "mbedtls/ecdsa.h"
00042 #endif
00043 
00044 #include <limits.h>
00045 
00046 /* Implementation that should never be optimized out by the compiler */
00047 static void mbedtls_zeroize( void *v, size_t n ) {
00048     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
00049 }
00050 
00051 /*
00052  * Initialise a mbedtls_pk_context
00053  */
00054 void mbedtls_pk_init( mbedtls_pk_context *ctx )
00055 {
00056     if( ctx == NULL )
00057         return;
00058 
00059     ctx->pk_info = NULL;
00060     ctx->pk_ctx = NULL;
00061 }
00062 
00063 /*
00064  * Free (the components of) a mbedtls_pk_context
00065  */
00066 void mbedtls_pk_free( mbedtls_pk_context *ctx )
00067 {
00068     if( ctx == NULL || ctx->pk_info == NULL )
00069         return;
00070 
00071     ctx->pk_info->ctx_free_func( ctx->pk_ctx );
00072 
00073     mbedtls_zeroize( ctx, sizeof( mbedtls_pk_context ) );
00074 }
00075 
00076 /*
00077  * Get pk_info structure from type
00078  */
00079 const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
00080 {
00081     switch( pk_type ) {
00082 #if defined(MBEDTLS_RSA_C)
00083         case MBEDTLS_PK_RSA:
00084             return( &mbedtls_rsa_info );
00085 #endif
00086 #if defined(MBEDTLS_ECP_C)
00087         case MBEDTLS_PK_ECKEY:
00088             return( &mbedtls_eckey_info );
00089         case MBEDTLS_PK_ECKEY_DH:
00090             return( &mbedtls_eckeydh_info );
00091 #endif
00092 #if defined(MBEDTLS_ECDSA_C)
00093         case MBEDTLS_PK_ECDSA:
00094             return( &mbedtls_ecdsa_info );
00095 #endif
00096         /* MBEDTLS_PK_RSA_ALT omitted on purpose */
00097         default:
00098             return( NULL );
00099     }
00100 }
00101 
00102 /*
00103  * Initialise context
00104  */
00105 int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
00106 {
00107     if( ctx == NULL || info == NULL || ctx->pk_info != NULL )
00108         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
00109 
00110     if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
00111         return( MBEDTLS_ERR_PK_ALLOC_FAILED );
00112 
00113     ctx->pk_info = info;
00114 
00115     return( 0 );
00116 }
00117 
00118 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
00119 /*
00120  * Initialize an RSA-alt context
00121  */
00122 int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
00123                          mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
00124                          mbedtls_pk_rsa_alt_sign_func sign_func,
00125                          mbedtls_pk_rsa_alt_key_len_func key_len_func )
00126 {
00127     mbedtls_rsa_alt_context *rsa_alt;
00128     const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
00129 
00130     if( ctx == NULL || ctx->pk_info != NULL )
00131         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
00132 
00133     if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
00134         return( MBEDTLS_ERR_PK_ALLOC_FAILED );
00135 
00136     ctx->pk_info = info;
00137 
00138     rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
00139 
00140     rsa_alt->key = key;
00141     rsa_alt->decrypt_func = decrypt_func;
00142     rsa_alt->sign_func = sign_func;
00143     rsa_alt->key_len_func = key_len_func;
00144 
00145     return( 0 );
00146 }
00147 #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
00148 
00149 /*
00150  * Tell if a PK can do the operations of the given type
00151  */
00152 int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
00153 {
00154     /* null or NONE context can't do anything */
00155     if( ctx == NULL || ctx->pk_info == NULL )
00156         return( 0 );
00157 
00158     return( ctx->pk_info->can_do( type ) );
00159 }
00160 
00161 /*
00162  * Helper for mbedtls_pk_sign and mbedtls_pk_verify
00163  */
00164 static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
00165 {
00166     const mbedtls_md_info_t *md_info;
00167 
00168     if( *hash_len != 0 )
00169         return( 0 );
00170 
00171     if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
00172         return( -1 );
00173 
00174     *hash_len = mbedtls_md_get_size( md_info );
00175     return( 0 );
00176 }
00177 
00178 /*
00179  * Verify a signature
00180  */
00181 int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
00182                const unsigned char *hash, size_t hash_len,
00183                const unsigned char *sig, size_t sig_len )
00184 {
00185     if( ctx == NULL || ctx->pk_info == NULL ||
00186         pk_hashlen_helper( md_alg, &hash_len ) != 0 )
00187         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
00188 
00189     if( ctx->pk_info->verify_func == NULL )
00190         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
00191 
00192     return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
00193                                        sig, sig_len ) );
00194 }
00195 
00196 /*
00197  * Verify a signature with options
00198  */
00199 int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
00200                    mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
00201                    const unsigned char *hash, size_t hash_len,
00202                    const unsigned char *sig, size_t sig_len )
00203 {
00204     if( ctx == NULL || ctx->pk_info == NULL )
00205         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
00206 
00207     if( ! mbedtls_pk_can_do( ctx, type ) )
00208         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
00209 
00210     if( type == MBEDTLS_PK_RSASSA_PSS )
00211     {
00212 #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
00213         int ret;
00214         const mbedtls_pk_rsassa_pss_options *pss_opts;
00215 
00216 #if defined(MBEDTLS_HAVE_INT64)
00217         if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
00218             return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
00219 #endif /* MBEDTLS_HAVE_INT64 */
00220 
00221         if( options == NULL )
00222             return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
00223 
00224         pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
00225 
00226         if( sig_len < mbedtls_pk_get_len( ctx ) )
00227             return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
00228 
00229         ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ),
00230                 NULL, NULL, MBEDTLS_RSA_PUBLIC,
00231                 md_alg, (unsigned int) hash_len, hash,
00232                 pss_opts->mgf1_hash_id,
00233                 pss_opts->expected_salt_len,
00234                 sig );
00235         if( ret != 0 )
00236             return( ret );
00237 
00238         if( sig_len > mbedtls_pk_get_len( ctx ) )
00239             return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
00240 
00241         return( 0 );
00242 #else
00243         return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
00244 #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
00245     }
00246 
00247     /* General case: no options */
00248     if( options != NULL )
00249         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
00250 
00251     return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
00252 }
00253 
00254 /*
00255  * Make a signature
00256  */
00257 int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
00258              const unsigned char *hash, size_t hash_len,
00259              unsigned char *sig, size_t *sig_len,
00260              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
00261 {
00262     if( ctx == NULL || ctx->pk_info == NULL ||
00263         pk_hashlen_helper( md_alg, &hash_len ) != 0 )
00264         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
00265 
00266     if( ctx->pk_info->sign_func == NULL )
00267         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
00268 
00269     return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
00270                                      sig, sig_len, f_rng, p_rng ) );
00271 }
00272 
00273 /*
00274  * Decrypt message
00275  */
00276 int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
00277                 const unsigned char *input, size_t ilen,
00278                 unsigned char *output, size_t *olen, size_t osize,
00279                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
00280 {
00281     if( ctx == NULL || ctx->pk_info == NULL )
00282         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
00283 
00284     if( ctx->pk_info->decrypt_func == NULL )
00285         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
00286 
00287     return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
00288                 output, olen, osize, f_rng, p_rng ) );
00289 }
00290 
00291 /*
00292  * Encrypt message
00293  */
00294 int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
00295                 const unsigned char *input, size_t ilen,
00296                 unsigned char *output, size_t *olen, size_t osize,
00297                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
00298 {
00299     if( ctx == NULL || ctx->pk_info == NULL )
00300         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
00301 
00302     if( ctx->pk_info->encrypt_func == NULL )
00303         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
00304 
00305     return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
00306                 output, olen, osize, f_rng, p_rng ) );
00307 }
00308 
00309 /*
00310  * Check public-private key pair
00311  */
00312 int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
00313 {
00314     if( pub == NULL || pub->pk_info == NULL ||
00315         prv == NULL || prv->pk_info == NULL ||
00316         prv->pk_info->check_pair_func == NULL )
00317     {
00318         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
00319     }
00320 
00321     if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
00322     {
00323         if( pub->pk_info->type != MBEDTLS_PK_RSA )
00324             return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
00325     }
00326     else
00327     {
00328         if( pub->pk_info != prv->pk_info )
00329             return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
00330     }
00331 
00332     return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
00333 }
00334 
00335 /*
00336  * Get key size in bits
00337  */
00338 size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
00339 {
00340     if( ctx == NULL || ctx->pk_info == NULL )
00341         return( 0 );
00342 
00343     return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) );
00344 }
00345 
00346 /*
00347  * Export debug information
00348  */
00349 int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
00350 {
00351     if( ctx == NULL || ctx->pk_info == NULL )
00352         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
00353 
00354     if( ctx->pk_info->debug_func == NULL )
00355         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
00356 
00357     ctx->pk_info->debug_func( ctx->pk_ctx, items );
00358     return( 0 );
00359 }
00360 
00361 /*
00362  * Access the PK type name
00363  */
00364 const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx )
00365 {
00366     if( ctx == NULL || ctx->pk_info == NULL )
00367         return( "invalid PK" );
00368 
00369     return( ctx->pk_info->name );
00370 }
00371 
00372 /*
00373  * Access the PK type
00374  */
00375 mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
00376 {
00377     if( ctx == NULL || ctx->pk_info == NULL )
00378         return( MBEDTLS_PK_NONE );
00379 
00380     return( ctx->pk_info->type );
00381 }
00382 
00383 #endif /* MBEDTLS_PK_C */