You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by st...@apache.org on 2016/09/28 00:43:54 UTC
[28/51] [abbrv] [partial] incubator-mynewt-core git commit: directory
re-org, part 1
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/crypto/mbedtls/src/pk.c
----------------------------------------------------------------------
diff --git a/crypto/mbedtls/src/pk.c b/crypto/mbedtls/src/pk.c
new file mode 100644
index 0000000..10bd0a5
--- /dev/null
+++ b/crypto/mbedtls/src/pk.c
@@ -0,0 +1,374 @@
+/*
+ * Public Key abstraction layer
+ *
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PK_C)
+#include "mbedtls/pk.h"
+#include "mbedtls/pk_internal.h"
+
+#if defined(MBEDTLS_RSA_C)
+#include "mbedtls/rsa.h"
+#endif
+#if defined(MBEDTLS_ECP_C)
+#include "mbedtls/ecp.h"
+#endif
+#if defined(MBEDTLS_ECDSA_C)
+#include "mbedtls/ecdsa.h"
+#endif
+
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_zeroize( void *v, size_t n ) {
+ volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+}
+
+/*
+ * Initialise a mbedtls_pk_context
+ */
+void mbedtls_pk_init( mbedtls_pk_context *ctx )
+{
+ if( ctx == NULL )
+ return;
+
+ ctx->pk_info = NULL;
+ ctx->pk_ctx = NULL;
+}
+
+/*
+ * Free (the components of) a mbedtls_pk_context
+ */
+void mbedtls_pk_free( mbedtls_pk_context *ctx )
+{
+ if( ctx == NULL || ctx->pk_info == NULL )
+ return;
+
+ ctx->pk_info->ctx_free_func( ctx->pk_ctx );
+
+ mbedtls_zeroize( ctx, sizeof( mbedtls_pk_context ) );
+}
+
+/*
+ * Get pk_info structure from type
+ */
+const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
+{
+ switch( pk_type ) {
+#if defined(MBEDTLS_RSA_C)
+ case MBEDTLS_PK_RSA:
+ return( &mbedtls_rsa_info );
+#endif
+#if defined(MBEDTLS_ECP_C)
+ case MBEDTLS_PK_ECKEY:
+ return( &mbedtls_eckey_info );
+ case MBEDTLS_PK_ECKEY_DH:
+ return( &mbedtls_eckeydh_info );
+#endif
+#if defined(MBEDTLS_ECDSA_C)
+ case MBEDTLS_PK_ECDSA:
+ return( &mbedtls_ecdsa_info );
+#endif
+ /* MBEDTLS_PK_RSA_ALT omitted on purpose */
+ default:
+ return( NULL );
+ }
+}
+
+/*
+ * Initialise context
+ */
+int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
+{
+ if( ctx == NULL || info == NULL || ctx->pk_info != NULL )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
+ return( MBEDTLS_ERR_PK_ALLOC_FAILED );
+
+ ctx->pk_info = info;
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+/*
+ * Initialize an RSA-alt context
+ */
+int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
+ mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
+ mbedtls_pk_rsa_alt_sign_func sign_func,
+ mbedtls_pk_rsa_alt_key_len_func key_len_func )
+{
+ mbedtls_rsa_alt_context *rsa_alt;
+ const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
+
+ if( ctx == NULL || ctx->pk_info != NULL )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
+ return( MBEDTLS_ERR_PK_ALLOC_FAILED );
+
+ ctx->pk_info = info;
+
+ rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
+
+ rsa_alt->key = key;
+ rsa_alt->decrypt_func = decrypt_func;
+ rsa_alt->sign_func = sign_func;
+ rsa_alt->key_len_func = key_len_func;
+
+ return( 0 );
+}
+#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
+
+/*
+ * Tell if a PK can do the operations of the given type
+ */
+int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
+{
+ /* null or NONE context can't do anything */
+ if( ctx == NULL || ctx->pk_info == NULL )
+ return( 0 );
+
+ return( ctx->pk_info->can_do( type ) );
+}
+
+/*
+ * Helper for mbedtls_pk_sign and mbedtls_pk_verify
+ */
+static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
+{
+ const mbedtls_md_info_t *md_info;
+
+ if( *hash_len != 0 )
+ return( 0 );
+
+ if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
+ return( -1 );
+
+ *hash_len = mbedtls_md_get_size( md_info );
+ return( 0 );
+}
+
+/*
+ * Verify a signature
+ */
+int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ const unsigned char *sig, size_t sig_len )
+{
+ if( ctx == NULL || ctx->pk_info == NULL ||
+ pk_hashlen_helper( md_alg, &hash_len ) != 0 )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ if( ctx->pk_info->verify_func == NULL )
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+ return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
+ sig, sig_len ) );
+}
+
+/*
+ * Verify a signature with options
+ */
+int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
+ mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ const unsigned char *sig, size_t sig_len )
+{
+ if( ctx == NULL || ctx->pk_info == NULL )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ if( ! mbedtls_pk_can_do( ctx, type ) )
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+ if( type == MBEDTLS_PK_RSASSA_PSS )
+ {
+#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
+ int ret;
+ const mbedtls_pk_rsassa_pss_options *pss_opts;
+
+ if( options == NULL )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
+
+ if( sig_len < mbedtls_pk_get_len( ctx ) )
+ return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
+
+ ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ),
+ NULL, NULL, MBEDTLS_RSA_PUBLIC,
+ md_alg, (unsigned int) hash_len, hash,
+ pss_opts->mgf1_hash_id,
+ pss_opts->expected_salt_len,
+ sig );
+ if( ret != 0 )
+ return( ret );
+
+ if( sig_len > mbedtls_pk_get_len( ctx ) )
+ return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
+
+ return( 0 );
+#else
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+#endif
+ }
+
+ /* General case: no options */
+ if( options != NULL )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
+}
+
+/*
+ * Make a signature
+ */
+int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_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 )
+{
+ if( ctx == NULL || ctx->pk_info == NULL ||
+ pk_hashlen_helper( md_alg, &hash_len ) != 0 )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ if( ctx->pk_info->sign_func == NULL )
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+ return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
+ sig, sig_len, f_rng, p_rng ) );
+}
+
+/*
+ * Decrypt message
+ */
+int mbedtls_pk_decrypt( mbedtls_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 )
+{
+ if( ctx == NULL || ctx->pk_info == NULL )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ if( ctx->pk_info->decrypt_func == NULL )
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+ return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
+ output, olen, osize, f_rng, p_rng ) );
+}
+
+/*
+ * Encrypt message
+ */
+int mbedtls_pk_encrypt( mbedtls_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 )
+{
+ if( ctx == NULL || ctx->pk_info == NULL )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ if( ctx->pk_info->encrypt_func == NULL )
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+ return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
+ output, olen, osize, f_rng, p_rng ) );
+}
+
+/*
+ * Check public-private key pair
+ */
+int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
+{
+ if( pub == NULL || pub->pk_info == NULL ||
+ prv == NULL || prv->pk_info == NULL ||
+ prv->pk_info->check_pair_func == NULL )
+ {
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+ }
+
+ if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
+ {
+ if( pub->pk_info->type != MBEDTLS_PK_RSA )
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+ }
+ else
+ {
+ if( pub->pk_info != prv->pk_info )
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+ }
+
+ return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
+}
+
+/*
+ * Get key size in bits
+ */
+size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
+{
+ if( ctx == NULL || ctx->pk_info == NULL )
+ return( 0 );
+
+ return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) );
+}
+
+/*
+ * Export debug information
+ */
+int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
+{
+ if( ctx == NULL || ctx->pk_info == NULL )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ if( ctx->pk_info->debug_func == NULL )
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+ ctx->pk_info->debug_func( ctx->pk_ctx, items );
+ return( 0 );
+}
+
+/*
+ * Access the PK type name
+ */
+const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx )
+{
+ if( ctx == NULL || ctx->pk_info == NULL )
+ return( "invalid PK" );
+
+ return( ctx->pk_info->name );
+}
+
+/*
+ * Access the PK type
+ */
+mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
+{
+ if( ctx == NULL || ctx->pk_info == NULL )
+ return( MBEDTLS_PK_NONE );
+
+ return( ctx->pk_info->type );
+}
+
+#endif /* MBEDTLS_PK_C */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/crypto/mbedtls/src/pk_wrap.c
----------------------------------------------------------------------
diff --git a/crypto/mbedtls/src/pk_wrap.c b/crypto/mbedtls/src/pk_wrap.c
new file mode 100644
index 0000000..712ad48
--- /dev/null
+++ b/crypto/mbedtls/src/pk_wrap.c
@@ -0,0 +1,495 @@
+/*
+ * Public Key abstraction layer: wrapper functions
+ *
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PK_C)
+#include "mbedtls/pk_internal.h"
+
+/* Even if RSA not activated, for the sake of RSA-alt */
+#include "mbedtls/rsa.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_ECP_C)
+#include "mbedtls/ecp.h"
+#endif
+
+#if defined(MBEDTLS_ECDSA_C)
+#include "mbedtls/ecdsa.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_zeroize( void *v, size_t n ) {
+ volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+}
+#endif
+
+#if defined(MBEDTLS_RSA_C)
+static int rsa_can_do( mbedtls_pk_type_t type )
+{
+ return( type == MBEDTLS_PK_RSA ||
+ type == MBEDTLS_PK_RSASSA_PSS );
+}
+
+static size_t rsa_get_bitlen( const void *ctx )
+{
+ return( 8 * ((const mbedtls_rsa_context *) ctx)->len );
+}
+
+static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ const unsigned char *sig, size_t sig_len )
+{
+ int ret;
+
+ if( sig_len < ((mbedtls_rsa_context *) ctx)->len )
+ return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
+
+ if( ( ret = mbedtls_rsa_pkcs1_verify( (mbedtls_rsa_context *) ctx, NULL, NULL,
+ MBEDTLS_RSA_PUBLIC, md_alg,
+ (unsigned int) hash_len, hash, sig ) ) != 0 )
+ return( ret );
+
+ if( sig_len > ((mbedtls_rsa_context *) ctx)->len )
+ return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
+
+ return( 0 );
+}
+
+static int rsa_sign_wrap( void *ctx, mbedtls_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 )
+{
+ *sig_len = ((mbedtls_rsa_context *) ctx)->len;
+
+ return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
+ md_alg, (unsigned int) hash_len, hash, sig ) );
+}
+
+static int rsa_decrypt_wrap( 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 )
+{
+ if( ilen != ((mbedtls_rsa_context *) ctx)->len )
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+ return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, f_rng, p_rng,
+ MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
+}
+
+static int rsa_encrypt_wrap( 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 )
+{
+ *olen = ((mbedtls_rsa_context *) ctx)->len;
+
+ if( *olen > osize )
+ return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
+
+ return( mbedtls_rsa_pkcs1_encrypt( (mbedtls_rsa_context *) ctx,
+ f_rng, p_rng, MBEDTLS_RSA_PUBLIC, ilen, input, output ) );
+}
+
+static int rsa_check_pair_wrap( const void *pub, const void *prv )
+{
+ return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
+ (const mbedtls_rsa_context *) prv ) );
+}
+
+static void *rsa_alloc_wrap( void )
+{
+ void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );
+
+ if( ctx != NULL )
+ mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );
+
+ return( ctx );
+}
+
+static void rsa_free_wrap( void *ctx )
+{
+ mbedtls_rsa_free( (mbedtls_rsa_context *) ctx );
+ mbedtls_free( ctx );
+}
+
+static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )
+{
+ items->type = MBEDTLS_PK_DEBUG_MPI;
+ items->name = "rsa.N";
+ items->value = &( ((mbedtls_rsa_context *) ctx)->N );
+
+ items++;
+
+ items->type = MBEDTLS_PK_DEBUG_MPI;
+ items->name = "rsa.E";
+ items->value = &( ((mbedtls_rsa_context *) ctx)->E );
+}
+
+const mbedtls_pk_info_t mbedtls_rsa_info = {
+ MBEDTLS_PK_RSA,
+ "RSA",
+ rsa_get_bitlen,
+ rsa_can_do,
+ rsa_verify_wrap,
+ rsa_sign_wrap,
+ rsa_decrypt_wrap,
+ rsa_encrypt_wrap,
+ rsa_check_pair_wrap,
+ rsa_alloc_wrap,
+ rsa_free_wrap,
+ rsa_debug,
+};
+#endif /* MBEDTLS_RSA_C */
+
+#if defined(MBEDTLS_ECP_C)
+/*
+ * Generic EC key
+ */
+static int eckey_can_do( mbedtls_pk_type_t type )
+{
+ return( type == MBEDTLS_PK_ECKEY ||
+ type == MBEDTLS_PK_ECKEY_DH ||
+ type == MBEDTLS_PK_ECDSA );
+}
+
+static size_t eckey_get_bitlen( const void *ctx )
+{
+ return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits );
+}
+
+#if defined(MBEDTLS_ECDSA_C)
+/* Forward declarations */
+static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ const unsigned char *sig, size_t sig_len );
+
+static int ecdsa_sign_wrap( void *ctx, mbedtls_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 );
+
+static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ const unsigned char *sig, size_t sig_len )
+{
+ int ret;
+ mbedtls_ecdsa_context ecdsa;
+
+ mbedtls_ecdsa_init( &ecdsa );
+
+ if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
+ ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
+
+ mbedtls_ecdsa_free( &ecdsa );
+
+ return( ret );
+}
+
+static int eckey_sign_wrap( void *ctx, mbedtls_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 )
+{
+ int ret;
+ mbedtls_ecdsa_context ecdsa;
+
+ mbedtls_ecdsa_init( &ecdsa );
+
+ if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
+ ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
+ f_rng, p_rng );
+
+ mbedtls_ecdsa_free( &ecdsa );
+
+ return( ret );
+}
+
+#endif /* MBEDTLS_ECDSA_C */
+
+static int eckey_check_pair( const void *pub, const void *prv )
+{
+ return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
+ (const mbedtls_ecp_keypair *) prv ) );
+}
+
+static void *eckey_alloc_wrap( void )
+{
+ void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
+
+ if( ctx != NULL )
+ mbedtls_ecp_keypair_init( ctx );
+
+ return( ctx );
+}
+
+static void eckey_free_wrap( void *ctx )
+{
+ mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx );
+ mbedtls_free( ctx );
+}
+
+static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items )
+{
+ items->type = MBEDTLS_PK_DEBUG_ECP;
+ items->name = "eckey.Q";
+ items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q );
+}
+
+const mbedtls_pk_info_t mbedtls_eckey_info = {
+ MBEDTLS_PK_ECKEY,
+ "EC",
+ eckey_get_bitlen,
+ eckey_can_do,
+#if defined(MBEDTLS_ECDSA_C)
+ eckey_verify_wrap,
+ eckey_sign_wrap,
+#else
+ NULL,
+ NULL,
+#endif
+ NULL,
+ NULL,
+ eckey_check_pair,
+ eckey_alloc_wrap,
+ eckey_free_wrap,
+ eckey_debug,
+};
+
+/*
+ * EC key restricted to ECDH
+ */
+static int eckeydh_can_do( mbedtls_pk_type_t type )
+{
+ return( type == MBEDTLS_PK_ECKEY ||
+ type == MBEDTLS_PK_ECKEY_DH );
+}
+
+const mbedtls_pk_info_t mbedtls_eckeydh_info = {
+ MBEDTLS_PK_ECKEY_DH,
+ "EC_DH",
+ eckey_get_bitlen, /* Same underlying key structure */
+ eckeydh_can_do,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ eckey_check_pair,
+ eckey_alloc_wrap, /* Same underlying key structure */
+ eckey_free_wrap, /* Same underlying key structure */
+ eckey_debug, /* Same underlying key structure */
+};
+#endif /* MBEDTLS_ECP_C */
+
+#if defined(MBEDTLS_ECDSA_C)
+static int ecdsa_can_do( mbedtls_pk_type_t type )
+{
+ return( type == MBEDTLS_PK_ECDSA );
+}
+
+static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ const unsigned char *sig, size_t sig_len )
+{
+ int ret;
+ ((void) md_alg);
+
+ ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
+ hash, hash_len, sig, sig_len );
+
+ if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
+ return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
+
+ return( ret );
+}
+
+static int ecdsa_sign_wrap( void *ctx, mbedtls_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 )
+{
+ return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
+ md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
+}
+
+static void *ecdsa_alloc_wrap( void )
+{
+ void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
+
+ if( ctx != NULL )
+ mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
+
+ return( ctx );
+}
+
+static void ecdsa_free_wrap( void *ctx )
+{
+ mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
+ mbedtls_free( ctx );
+}
+
+const mbedtls_pk_info_t mbedtls_ecdsa_info = {
+ MBEDTLS_PK_ECDSA,
+ "ECDSA",
+ eckey_get_bitlen, /* Compatible key structures */
+ ecdsa_can_do,
+ ecdsa_verify_wrap,
+ ecdsa_sign_wrap,
+ NULL,
+ NULL,
+ eckey_check_pair, /* Compatible key structures */
+ ecdsa_alloc_wrap,
+ ecdsa_free_wrap,
+ eckey_debug, /* Compatible key structures */
+};
+#endif /* MBEDTLS_ECDSA_C */
+
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+/*
+ * Support for alternative RSA-private implementations
+ */
+
+static int rsa_alt_can_do( mbedtls_pk_type_t type )
+{
+ return( type == MBEDTLS_PK_RSA );
+}
+
+static size_t rsa_alt_get_bitlen( const void *ctx )
+{
+ const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
+
+ return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
+}
+
+static int rsa_alt_sign_wrap( void *ctx, mbedtls_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 )
+{
+ mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
+
+ *sig_len = rsa_alt->key_len_func( rsa_alt->key );
+
+ return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
+ md_alg, (unsigned int) hash_len, hash, sig ) );
+}
+
+static int rsa_alt_decrypt_wrap( 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 )
+{
+ mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
+
+ ((void) f_rng);
+ ((void) p_rng);
+
+ if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+ return( rsa_alt->decrypt_func( rsa_alt->key,
+ MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
+}
+
+#if defined(MBEDTLS_RSA_C)
+static int rsa_alt_check_pair( const void *pub, const void *prv )
+{
+ unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
+ unsigned char hash[32];
+ size_t sig_len = 0;
+ int ret;
+
+ if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
+ return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+
+ memset( hash, 0x2a, sizeof( hash ) );
+
+ if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
+ hash, sizeof( hash ),
+ sig, &sig_len, NULL, NULL ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
+ hash, sizeof( hash ), sig, sig_len ) != 0 )
+ {
+ return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+ }
+
+ return( 0 );
+}
+#endif /* MBEDTLS_RSA_C */
+
+static void *rsa_alt_alloc_wrap( void )
+{
+ void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
+
+ if( ctx != NULL )
+ memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
+
+ return( ctx );
+}
+
+static void rsa_alt_free_wrap( void *ctx )
+{
+ mbedtls_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
+ mbedtls_free( ctx );
+}
+
+const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
+ MBEDTLS_PK_RSA_ALT,
+ "RSA-alt",
+ rsa_alt_get_bitlen,
+ rsa_alt_can_do,
+ NULL,
+ rsa_alt_sign_wrap,
+ rsa_alt_decrypt_wrap,
+ NULL,
+#if defined(MBEDTLS_RSA_C)
+ rsa_alt_check_pair,
+#else
+ NULL,
+#endif
+ rsa_alt_alloc_wrap,
+ rsa_alt_free_wrap,
+ NULL,
+};
+
+#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
+
+#endif /* MBEDTLS_PK_C */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/crypto/mbedtls/src/pkcs11.c
----------------------------------------------------------------------
diff --git a/crypto/mbedtls/src/pkcs11.c b/crypto/mbedtls/src/pkcs11.c
new file mode 100644
index 0000000..0ea6425
--- /dev/null
+++ b/crypto/mbedtls/src/pkcs11.c
@@ -0,0 +1,240 @@
+/**
+ * \file pkcs11.c
+ *
+ * \brief Wrapper for PKCS#11 library libpkcs11-helper
+ *
+ * \author Adriaan de Jong <de...@fox-it.com>
+ *
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#include "mbedtls/pkcs11.h"
+
+#if defined(MBEDTLS_PKCS11_C)
+
+#include "mbedtls/md.h"
+#include "mbedtls/oid.h"
+#include "mbedtls/x509_crt.h"
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+#include <string.h>
+
+void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx )
+{
+ memset( ctx, 0, sizeof( mbedtls_pkcs11_context ) );
+}
+
+int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11_cert )
+{
+ int ret = 1;
+ unsigned char *cert_blob = NULL;
+ size_t cert_blob_size = 0;
+
+ if( cert == NULL )
+ {
+ ret = 2;
+ goto cleanup;
+ }
+
+ if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL,
+ &cert_blob_size ) != CKR_OK )
+ {
+ ret = 3;
+ goto cleanup;
+ }
+
+ cert_blob = mbedtls_calloc( 1, cert_blob_size );
+ if( NULL == cert_blob )
+ {
+ ret = 4;
+ goto cleanup;
+ }
+
+ if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob,
+ &cert_blob_size ) != CKR_OK )
+ {
+ ret = 5;
+ goto cleanup;
+ }
+
+ if( 0 != mbedtls_x509_crt_parse( cert, cert_blob, cert_blob_size ) )
+ {
+ ret = 6;
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ if( NULL != cert_blob )
+ mbedtls_free( cert_blob );
+
+ return( ret );
+}
+
+
+int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key,
+ pkcs11h_certificate_t pkcs11_cert )
+{
+ int ret = 1;
+ mbedtls_x509_crt cert;
+
+ mbedtls_x509_crt_init( &cert );
+
+ if( priv_key == NULL )
+ goto cleanup;
+
+ if( 0 != mbedtls_pkcs11_x509_cert_bind( &cert, pkcs11_cert ) )
+ goto cleanup;
+
+ priv_key->len = mbedtls_pk_get_len( &cert.pk );
+ priv_key->pkcs11h_cert = pkcs11_cert;
+
+ ret = 0;
+
+cleanup:
+ mbedtls_x509_crt_free( &cert );
+
+ return( ret );
+}
+
+void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key )
+{
+ if( NULL != priv_key )
+ pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
+}
+
+int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx,
+ int mode, size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len )
+{
+ size_t input_len, output_len;
+
+ if( NULL == ctx )
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+ if( MBEDTLS_RSA_PRIVATE != mode )
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+ output_len = input_len = ctx->len;
+
+ if( input_len < 16 || input_len > output_max_len )
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+ /* Determine size of output buffer */
+ if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
+ input_len, NULL, &output_len ) != CKR_OK )
+ {
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ if( output_len > output_max_len )
+ return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
+
+ if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
+ input_len, output, &output_len ) != CKR_OK )
+ {
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+ }
+ *olen = output_len;
+ return( 0 );
+}
+
+int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx,
+ int mode,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig )
+{
+ size_t sig_len = 0, asn_len = 0, oid_size = 0;
+ unsigned char *p = sig;
+ const char *oid;
+
+ if( NULL == ctx )
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+ if( MBEDTLS_RSA_PRIVATE != mode )
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+ if( md_alg != MBEDTLS_MD_NONE )
+ {
+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
+ if( md_info == NULL )
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+ if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+ hashlen = mbedtls_md_get_size( md_info );
+ asn_len = 10 + oid_size;
+ }
+
+ sig_len = ctx->len;
+ if( hashlen > sig_len || asn_len > sig_len ||
+ hashlen + asn_len > sig_len )
+ {
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ if( md_alg != MBEDTLS_MD_NONE )
+ {
+ /*
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * digest Digest }
+ *
+ * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * Digest ::= OCTET STRING
+ */
+ *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
+ *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
+ *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
+ *p++ = (unsigned char) ( 0x04 + oid_size );
+ *p++ = MBEDTLS_ASN1_OID;
+ *p++ = oid_size & 0xFF;
+ memcpy( p, oid, oid_size );
+ p += oid_size;
+ *p++ = MBEDTLS_ASN1_NULL;
+ *p++ = 0x00;
+ *p++ = MBEDTLS_ASN1_OCTET_STRING;
+ *p++ = hashlen;
+ }
+
+ memcpy( p, hash, hashlen );
+
+ if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
+ asn_len + hashlen, sig, &sig_len ) != CKR_OK )
+ {
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ return( 0 );
+}
+
+#endif /* defined(MBEDTLS_PKCS11_C) */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/crypto/mbedtls/src/pkcs12.c
----------------------------------------------------------------------
diff --git a/crypto/mbedtls/src/pkcs12.c b/crypto/mbedtls/src/pkcs12.c
new file mode 100644
index 0000000..7023b9d
--- /dev/null
+++ b/crypto/mbedtls/src/pkcs12.c
@@ -0,0 +1,365 @@
+/*
+ * PKCS#12 Personal Information Exchange Syntax
+ *
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ * The PKCS #12 Personal Information Exchange Syntax Standard v1.1
+ *
+ * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf
+ * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PKCS12_C)
+
+#include "mbedtls/pkcs12.h"
+#include "mbedtls/asn1.h"
+#include "mbedtls/cipher.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_ARC4_C)
+#include "mbedtls/arc4.h"
+#endif
+
+#if defined(MBEDTLS_DES_C)
+#include "mbedtls/des.h"
+#endif
+
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_zeroize( void *v, size_t n ) {
+ volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+}
+
+static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
+ mbedtls_asn1_buf *salt, int *iterations )
+{
+ int ret;
+ unsigned char **p = ¶ms->p;
+ const unsigned char *end = params->p + params->len;
+
+ /*
+ * pkcs-12PbeParams ::= SEQUENCE {
+ * salt OCTET STRING,
+ * iterations INTEGER
+ * }
+ *
+ */
+ if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
+ return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT +
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+
+ if( ( ret = mbedtls_asn1_get_tag( p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+ return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
+
+ salt->p = *p;
+ *p += salt->len;
+
+ if( ( ret = mbedtls_asn1_get_int( p, end, iterations ) ) != 0 )
+ return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
+
+ if( *p != end )
+ return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+ return( 0 );
+}
+
+#define PKCS12_MAX_PWDLEN 128
+
+static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type,
+ const unsigned char *pwd, size_t pwdlen,
+ unsigned char *key, size_t keylen,
+ unsigned char *iv, size_t ivlen )
+{
+ int ret, iterations;
+ mbedtls_asn1_buf salt;
+ size_t i;
+ unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2];
+
+ if( pwdlen > PKCS12_MAX_PWDLEN )
+ return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
+
+ memset( &salt, 0, sizeof(mbedtls_asn1_buf) );
+ memset( &unipwd, 0, sizeof(unipwd) );
+
+ if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt,
+ &iterations ) ) != 0 )
+ return( ret );
+
+ for( i = 0; i < pwdlen; i++ )
+ unipwd[i * 2 + 1] = pwd[i];
+
+ if( ( ret = mbedtls_pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2,
+ salt.p, salt.len, md_type,
+ MBEDTLS_PKCS12_DERIVE_KEY, iterations ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( iv == NULL || ivlen == 0 )
+ return( 0 );
+
+ if( ( ret = mbedtls_pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2,
+ salt.p, salt.len, md_type,
+ MBEDTLS_PKCS12_DERIVE_IV, iterations ) ) != 0 )
+ {
+ return( ret );
+ }
+ return( 0 );
+}
+
+#undef PKCS12_MAX_PWDLEN
+
+int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode,
+ const unsigned char *pwd, size_t pwdlen,
+ const unsigned char *data, size_t len,
+ unsigned char *output )
+{
+#if !defined(MBEDTLS_ARC4_C)
+ ((void) pbe_params);
+ ((void) mode);
+ ((void) pwd);
+ ((void) pwdlen);
+ ((void) data);
+ ((void) len);
+ ((void) output);
+ return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
+#else
+ int ret;
+ unsigned char key[16];
+ mbedtls_arc4_context ctx;
+ ((void) mode);
+
+ mbedtls_arc4_init( &ctx );
+
+ if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, MBEDTLS_MD_SHA1,
+ pwd, pwdlen,
+ key, 16, NULL, 0 ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ mbedtls_arc4_setup( &ctx, key, 16 );
+ if( ( ret = mbedtls_arc4_crypt( &ctx, len, data, output ) ) != 0 )
+ goto exit;
+
+exit:
+ mbedtls_zeroize( key, sizeof( key ) );
+ mbedtls_arc4_free( &ctx );
+
+ return( ret );
+#endif /* MBEDTLS_ARC4_C */
+}
+
+int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode,
+ mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
+ const unsigned char *pwd, size_t pwdlen,
+ const unsigned char *data, size_t len,
+ unsigned char *output )
+{
+ int ret, keylen = 0;
+ unsigned char key[32];
+ unsigned char iv[16];
+ const mbedtls_cipher_info_t *cipher_info;
+ mbedtls_cipher_context_t cipher_ctx;
+ size_t olen = 0;
+
+ cipher_info = mbedtls_cipher_info_from_type( cipher_type );
+ if( cipher_info == NULL )
+ return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
+
+ keylen = cipher_info->key_bitlen / 8;
+
+ if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen,
+ key, keylen,
+ iv, cipher_info->iv_size ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ mbedtls_cipher_init( &cipher_ctx );
+
+ if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 )
+ goto exit;
+
+ if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 )
+ goto exit;
+
+ if( ( ret = mbedtls_cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 )
+ goto exit;
+
+ if( ( ret = mbedtls_cipher_reset( &cipher_ctx ) ) != 0 )
+ goto exit;
+
+ if( ( ret = mbedtls_cipher_update( &cipher_ctx, data, len,
+ output, &olen ) ) != 0 )
+ {
+ goto exit;
+ }
+
+ if( ( ret = mbedtls_cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
+ ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH;
+
+exit:
+ mbedtls_zeroize( key, sizeof( key ) );
+ mbedtls_zeroize( iv, sizeof( iv ) );
+ mbedtls_cipher_free( &cipher_ctx );
+
+ return( ret );
+}
+
+static void pkcs12_fill_buffer( unsigned char *data, size_t data_len,
+ const unsigned char *filler, size_t fill_len )
+{
+ unsigned char *p = data;
+ size_t use_len;
+
+ while( data_len > 0 )
+ {
+ use_len = ( data_len > fill_len ) ? fill_len : data_len;
+ memcpy( p, filler, use_len );
+ p += use_len;
+ data_len -= use_len;
+ }
+}
+
+int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
+ const unsigned char *pwd, size_t pwdlen,
+ const unsigned char *salt, size_t saltlen,
+ mbedtls_md_type_t md_type, int id, int iterations )
+{
+ int ret;
+ unsigned int j;
+
+ unsigned char diversifier[128];
+ unsigned char salt_block[128], pwd_block[128], hash_block[128];
+ unsigned char hash_output[MBEDTLS_MD_MAX_SIZE];
+ unsigned char *p;
+ unsigned char c;
+
+ size_t hlen, use_len, v, i;
+
+ const mbedtls_md_info_t *md_info;
+ mbedtls_md_context_t md_ctx;
+
+ // This version only allows max of 64 bytes of password or salt
+ if( datalen > 128 || pwdlen > 64 || saltlen > 64 )
+ return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
+
+ md_info = mbedtls_md_info_from_type( md_type );
+ if( md_info == NULL )
+ return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
+
+ mbedtls_md_init( &md_ctx );
+
+ if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+ return( ret );
+ hlen = mbedtls_md_get_size( md_info );
+
+ if( hlen <= 32 )
+ v = 64;
+ else
+ v = 128;
+
+ memset( diversifier, (unsigned char) id, v );
+
+ pkcs12_fill_buffer( salt_block, v, salt, saltlen );
+ pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen );
+
+ p = data;
+ while( datalen > 0 )
+ {
+ // Calculate hash( diversifier || salt_block || pwd_block )
+ if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
+ goto exit;
+
+ if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 )
+ goto exit;
+
+ if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 )
+ goto exit;
+
+ if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 )
+ goto exit;
+
+ if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 )
+ goto exit;
+
+ // Perform remaining ( iterations - 1 ) recursive hash calculations
+ for( i = 1; i < (size_t) iterations; i++ )
+ {
+ if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 )
+ goto exit;
+ }
+
+ use_len = ( datalen > hlen ) ? hlen : datalen;
+ memcpy( p, hash_output, use_len );
+ datalen -= use_len;
+ p += use_len;
+
+ if( datalen == 0 )
+ break;
+
+ // Concatenating copies of hash_output into hash_block (B)
+ pkcs12_fill_buffer( hash_block, v, hash_output, hlen );
+
+ // B += 1
+ for( i = v; i > 0; i-- )
+ if( ++hash_block[i - 1] != 0 )
+ break;
+
+ // salt_block += B
+ c = 0;
+ for( i = v; i > 0; i-- )
+ {
+ j = salt_block[i - 1] + hash_block[i - 1] + c;
+ c = (unsigned char) (j >> 8);
+ salt_block[i - 1] = j & 0xFF;
+ }
+
+ // pwd_block += B
+ c = 0;
+ for( i = v; i > 0; i-- )
+ {
+ j = pwd_block[i - 1] + hash_block[i - 1] + c;
+ c = (unsigned char) (j >> 8);
+ pwd_block[i - 1] = j & 0xFF;
+ }
+ }
+
+ ret = 0;
+
+exit:
+ mbedtls_zeroize( salt_block, sizeof( salt_block ) );
+ mbedtls_zeroize( pwd_block, sizeof( pwd_block ) );
+ mbedtls_zeroize( hash_block, sizeof( hash_block ) );
+ mbedtls_zeroize( hash_output, sizeof( hash_output ) );
+
+ mbedtls_md_free( &md_ctx );
+
+ return( ret );
+}
+
+#endif /* MBEDTLS_PKCS12_C */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/crypto/mbedtls/src/pkcs5.c
----------------------------------------------------------------------
diff --git a/crypto/mbedtls/src/pkcs5.c b/crypto/mbedtls/src/pkcs5.c
new file mode 100644
index 0000000..44af986
--- /dev/null
+++ b/crypto/mbedtls/src/pkcs5.c
@@ -0,0 +1,405 @@
+/**
+ * \file pkcs5.c
+ *
+ * \brief PKCS#5 functions
+ *
+ * \author Mathias Olsson <ma...@kompetensum.com>
+ *
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ * PKCS#5 includes PBKDF2 and more
+ *
+ * http://tools.ietf.org/html/rfc2898 (Specification)
+ * http://tools.ietf.org/html/rfc6070 (Test vectors)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PKCS5_C)
+
+#include "mbedtls/pkcs5.h"
+#include "mbedtls/asn1.h"
+#include "mbedtls/cipher.h"
+#include "mbedtls/oid.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif
+
+static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
+ mbedtls_asn1_buf *salt, int *iterations,
+ int *keylen, mbedtls_md_type_t *md_type )
+{
+ int ret;
+ mbedtls_asn1_buf prf_alg_oid;
+ unsigned char *p = params->p;
+ const unsigned char *end = params->p + params->len;
+
+ if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
+ return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ /*
+ * PBKDF2-params ::= SEQUENCE {
+ * salt OCTET STRING,
+ * iterationCount INTEGER,
+ * keyLength INTEGER OPTIONAL
+ * prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1
+ * }
+ *
+ */
+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+ return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+
+ salt->p = p;
+ p += salt->len;
+
+ if( ( ret = mbedtls_asn1_get_int( &p, end, iterations ) ) != 0 )
+ return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+
+ if( p == end )
+ return( 0 );
+
+ if( ( ret = mbedtls_asn1_get_int( &p, end, keylen ) ) != 0 )
+ {
+ if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+ return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ }
+
+ if( p == end )
+ return( 0 );
+
+ if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 )
+ return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+
+ if( MBEDTLS_OID_CMP( MBEDTLS_OID_HMAC_SHA1, &prf_alg_oid ) != 0 )
+ return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
+
+ *md_type = MBEDTLS_MD_SHA1;
+
+ if( p != end )
+ return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+ return( 0 );
+}
+
+int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
+ const unsigned char *pwd, size_t pwdlen,
+ const unsigned char *data, size_t datalen,
+ unsigned char *output )
+{
+ int ret, iterations = 0, keylen = 0;
+ unsigned char *p, *end;
+ mbedtls_asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params;
+ mbedtls_asn1_buf salt;
+ mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1;
+ unsigned char key[32], iv[32];
+ size_t olen = 0;
+ const mbedtls_md_info_t *md_info;
+ const mbedtls_cipher_info_t *cipher_info;
+ mbedtls_md_context_t md_ctx;
+ mbedtls_cipher_type_t cipher_alg;
+ mbedtls_cipher_context_t cipher_ctx;
+
+ p = pbe_params->p;
+ end = p + pbe_params->len;
+
+ /*
+ * PBES2-params ::= SEQUENCE {
+ * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
+ * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}
+ * }
+ */
+ if( pbe_params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
+ return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+
+ if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 )
+ return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+
+ // Only PBKDF2 supported at the moment
+ //
+ if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBKDF2, &kdf_alg_oid ) != 0 )
+ return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
+
+ if( ( ret = pkcs5_parse_pbkdf2_params( &kdf_alg_params,
+ &salt, &iterations, &keylen,
+ &md_type ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ md_info = mbedtls_md_info_from_type( md_type );
+ if( md_info == NULL )
+ return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
+
+ if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid,
+ &enc_scheme_params ) ) != 0 )
+ {
+ return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ }
+
+ if( mbedtls_oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 )
+ return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
+
+ cipher_info = mbedtls_cipher_info_from_type( cipher_alg );
+ if( cipher_info == NULL )
+ return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
+
+ /*
+ * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored
+ * since it is optional and we don't know if it was set or not
+ */
+ keylen = cipher_info->key_bitlen / 8;
+
+ if( enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING ||
+ enc_scheme_params.len != cipher_info->iv_size )
+ {
+ return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT );
+ }
+
+ mbedtls_md_init( &md_ctx );
+ mbedtls_cipher_init( &cipher_ctx );
+
+ memcpy( iv, enc_scheme_params.p, enc_scheme_params.len );
+
+ if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
+ goto exit;
+
+ if( ( ret = mbedtls_pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len,
+ iterations, keylen, key ) ) != 0 )
+ {
+ goto exit;
+ }
+
+ if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 )
+ goto exit;
+
+ if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 )
+ goto exit;
+
+ if( ( ret = mbedtls_cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len,
+ data, datalen, output, &olen ) ) != 0 )
+ ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH;
+
+exit:
+ mbedtls_md_free( &md_ctx );
+ mbedtls_cipher_free( &cipher_ctx );
+
+ return( ret );
+}
+
+int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password,
+ size_t plen, const unsigned char *salt, size_t slen,
+ unsigned int iteration_count,
+ uint32_t key_length, unsigned char *output )
+{
+ int ret, j;
+ unsigned int i;
+ unsigned char md1[MBEDTLS_MD_MAX_SIZE];
+ unsigned char work[MBEDTLS_MD_MAX_SIZE];
+ unsigned char md_size = mbedtls_md_get_size( ctx->md_info );
+ size_t use_len;
+ unsigned char *out_p = output;
+ unsigned char counter[4];
+
+ memset( counter, 0, 4 );
+ counter[3] = 1;
+
+ if( iteration_count > 0xFFFFFFFF )
+ return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA );
+
+ while( key_length )
+ {
+ // U1 ends up in work
+ //
+ if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
+ return( ret );
+
+ if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 )
+ return( ret );
+
+ if( ( ret = mbedtls_md_hmac_update( ctx, counter, 4 ) ) != 0 )
+ return( ret );
+
+ if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 )
+ return( ret );
+
+ memcpy( md1, work, md_size );
+
+ for( i = 1; i < iteration_count; i++ )
+ {
+ // U2 ends up in md1
+ //
+ if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
+ return( ret );
+
+ if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 )
+ return( ret );
+
+ if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 )
+ return( ret );
+
+ // U1 xor U2
+ //
+ for( j = 0; j < md_size; j++ )
+ work[j] ^= md1[j];
+ }
+
+ use_len = ( key_length < md_size ) ? key_length : md_size;
+ memcpy( out_p, work, use_len );
+
+ key_length -= (uint32_t) use_len;
+ out_p += use_len;
+
+ for( i = 4; i > 0; i-- )
+ if( ++counter[i - 1] != 0 )
+ break;
+ }
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_SELF_TEST)
+
+#if !defined(MBEDTLS_SHA1_C)
+int mbedtls_pkcs5_self_test( int verbose )
+{
+ if( verbose != 0 )
+ mbedtls_printf( " PBKDF2 (SHA1): skipped\n\n" );
+
+ return( 0 );
+}
+#else
+
+#define MAX_TESTS 6
+
+static const size_t plen[MAX_TESTS] =
+ { 8, 8, 8, 24, 9 };
+
+static const unsigned char password[MAX_TESTS][32] =
+{
+ "password",
+ "password",
+ "password",
+ "passwordPASSWORDpassword",
+ "pass\0word",
+};
+
+static const size_t slen[MAX_TESTS] =
+ { 4, 4, 4, 36, 5 };
+
+static const unsigned char salt[MAX_TESTS][40] =
+{
+ "salt",
+ "salt",
+ "salt",
+ "saltSALTsaltSALTsaltSALTsaltSALTsalt",
+ "sa\0lt",
+};
+
+static const uint32_t it_cnt[MAX_TESTS] =
+ { 1, 2, 4096, 4096, 4096 };
+
+static const uint32_t key_len[MAX_TESTS] =
+ { 20, 20, 20, 25, 16 };
+
+static const unsigned char result_key[MAX_TESTS][32] =
+{
+ { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
+ 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
+ 0x2f, 0xe0, 0x37, 0xa6 },
+ { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
+ 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
+ 0xd8, 0xde, 0x89, 0x57 },
+ { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
+ 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
+ 0x65, 0xa4, 0x29, 0xc1 },
+ { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
+ 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
+ 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
+ 0x38 },
+ { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
+ 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 },
+};
+
+int mbedtls_pkcs5_self_test( int verbose )
+{
+ mbedtls_md_context_t sha1_ctx;
+ const mbedtls_md_info_t *info_sha1;
+ int ret, i;
+ unsigned char key[64];
+
+ mbedtls_md_init( &sha1_ctx );
+
+ info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
+ if( info_sha1 == NULL )
+ {
+ ret = 1;
+ goto exit;
+ }
+
+ if( ( ret = mbedtls_md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
+
+ for( i = 0; i < MAX_TESTS; i++ )
+ {
+ if( verbose != 0 )
+ mbedtls_printf( " PBKDF2 (SHA1) #%d: ", i );
+
+ ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i],
+ slen[i], it_cnt[i], key_len[i], key );
+ if( ret != 0 ||
+ memcmp( result_key[i], key, key_len[i] ) != 0 )
+ {
+ if( verbose != 0 )
+ mbedtls_printf( "failed\n" );
+
+ ret = 1;
+ goto exit;
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+ }
+
+ mbedtls_printf( "\n" );
+
+exit:
+ mbedtls_md_free( &sha1_ctx );
+
+ return( ret );
+}
+#endif /* MBEDTLS_SHA1_C */
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_PKCS5_C */