nkjnm

Dependencies:   MAX44000 nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Committer:
nexpaq
Date:
Sat Sep 17 16:32:05 2016 +0000
Revision:
1:55a6170b404f
checking in for sharing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nexpaq 1:55a6170b404f 1 /**
nexpaq 1:55a6170b404f 2 * \file pkcs11.c
nexpaq 1:55a6170b404f 3 *
nexpaq 1:55a6170b404f 4 * \brief Wrapper for PKCS#11 library libpkcs11-helper
nexpaq 1:55a6170b404f 5 *
nexpaq 1:55a6170b404f 6 * \author Adriaan de Jong <dejong@fox-it.com>
nexpaq 1:55a6170b404f 7 *
nexpaq 1:55a6170b404f 8 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
nexpaq 1:55a6170b404f 9 * SPDX-License-Identifier: Apache-2.0
nexpaq 1:55a6170b404f 10 *
nexpaq 1:55a6170b404f 11 * Licensed under the Apache License, Version 2.0 (the "License"); you may
nexpaq 1:55a6170b404f 12 * not use this file except in compliance with the License.
nexpaq 1:55a6170b404f 13 * You may obtain a copy of the License at
nexpaq 1:55a6170b404f 14 *
nexpaq 1:55a6170b404f 15 * http://www.apache.org/licenses/LICENSE-2.0
nexpaq 1:55a6170b404f 16 *
nexpaq 1:55a6170b404f 17 * Unless required by applicable law or agreed to in writing, software
nexpaq 1:55a6170b404f 18 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
nexpaq 1:55a6170b404f 19 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nexpaq 1:55a6170b404f 20 * See the License for the specific language governing permissions and
nexpaq 1:55a6170b404f 21 * limitations under the License.
nexpaq 1:55a6170b404f 22 *
nexpaq 1:55a6170b404f 23 * This file is part of mbed TLS (https://tls.mbed.org)
nexpaq 1:55a6170b404f 24 */
nexpaq 1:55a6170b404f 25
nexpaq 1:55a6170b404f 26 #include "mbedtls/pkcs11.h"
nexpaq 1:55a6170b404f 27
nexpaq 1:55a6170b404f 28 #if defined(MBEDTLS_PKCS11_C)
nexpaq 1:55a6170b404f 29
nexpaq 1:55a6170b404f 30 #include "mbedtls/md.h"
nexpaq 1:55a6170b404f 31 #include "mbedtls/oid.h"
nexpaq 1:55a6170b404f 32 #include "mbedtls/x509_crt.h"
nexpaq 1:55a6170b404f 33
nexpaq 1:55a6170b404f 34 #if defined(MBEDTLS_PLATFORM_C)
nexpaq 1:55a6170b404f 35 #include "mbedtls/platform.h"
nexpaq 1:55a6170b404f 36 #else
nexpaq 1:55a6170b404f 37 #include <stdlib.h>
nexpaq 1:55a6170b404f 38 #define mbedtls_calloc calloc
nexpaq 1:55a6170b404f 39 #define mbedtls_free free
nexpaq 1:55a6170b404f 40 #endif
nexpaq 1:55a6170b404f 41
nexpaq 1:55a6170b404f 42 #include <string.h>
nexpaq 1:55a6170b404f 43
nexpaq 1:55a6170b404f 44 void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx )
nexpaq 1:55a6170b404f 45 {
nexpaq 1:55a6170b404f 46 memset( ctx, 0, sizeof( mbedtls_pkcs11_context ) );
nexpaq 1:55a6170b404f 47 }
nexpaq 1:55a6170b404f 48
nexpaq 1:55a6170b404f 49 int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11_cert )
nexpaq 1:55a6170b404f 50 {
nexpaq 1:55a6170b404f 51 int ret = 1;
nexpaq 1:55a6170b404f 52 unsigned char *cert_blob = NULL;
nexpaq 1:55a6170b404f 53 size_t cert_blob_size = 0;
nexpaq 1:55a6170b404f 54
nexpaq 1:55a6170b404f 55 if( cert == NULL )
nexpaq 1:55a6170b404f 56 {
nexpaq 1:55a6170b404f 57 ret = 2;
nexpaq 1:55a6170b404f 58 goto cleanup;
nexpaq 1:55a6170b404f 59 }
nexpaq 1:55a6170b404f 60
nexpaq 1:55a6170b404f 61 if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL,
nexpaq 1:55a6170b404f 62 &cert_blob_size ) != CKR_OK )
nexpaq 1:55a6170b404f 63 {
nexpaq 1:55a6170b404f 64 ret = 3;
nexpaq 1:55a6170b404f 65 goto cleanup;
nexpaq 1:55a6170b404f 66 }
nexpaq 1:55a6170b404f 67
nexpaq 1:55a6170b404f 68 cert_blob = mbedtls_calloc( 1, cert_blob_size );
nexpaq 1:55a6170b404f 69 if( NULL == cert_blob )
nexpaq 1:55a6170b404f 70 {
nexpaq 1:55a6170b404f 71 ret = 4;
nexpaq 1:55a6170b404f 72 goto cleanup;
nexpaq 1:55a6170b404f 73 }
nexpaq 1:55a6170b404f 74
nexpaq 1:55a6170b404f 75 if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob,
nexpaq 1:55a6170b404f 76 &cert_blob_size ) != CKR_OK )
nexpaq 1:55a6170b404f 77 {
nexpaq 1:55a6170b404f 78 ret = 5;
nexpaq 1:55a6170b404f 79 goto cleanup;
nexpaq 1:55a6170b404f 80 }
nexpaq 1:55a6170b404f 81
nexpaq 1:55a6170b404f 82 if( 0 != mbedtls_x509_crt_parse( cert, cert_blob, cert_blob_size ) )
nexpaq 1:55a6170b404f 83 {
nexpaq 1:55a6170b404f 84 ret = 6;
nexpaq 1:55a6170b404f 85 goto cleanup;
nexpaq 1:55a6170b404f 86 }
nexpaq 1:55a6170b404f 87
nexpaq 1:55a6170b404f 88 ret = 0;
nexpaq 1:55a6170b404f 89
nexpaq 1:55a6170b404f 90 cleanup:
nexpaq 1:55a6170b404f 91 if( NULL != cert_blob )
nexpaq 1:55a6170b404f 92 mbedtls_free( cert_blob );
nexpaq 1:55a6170b404f 93
nexpaq 1:55a6170b404f 94 return( ret );
nexpaq 1:55a6170b404f 95 }
nexpaq 1:55a6170b404f 96
nexpaq 1:55a6170b404f 97
nexpaq 1:55a6170b404f 98 int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key,
nexpaq 1:55a6170b404f 99 pkcs11h_certificate_t pkcs11_cert )
nexpaq 1:55a6170b404f 100 {
nexpaq 1:55a6170b404f 101 int ret = 1;
nexpaq 1:55a6170b404f 102 mbedtls_x509_crt cert;
nexpaq 1:55a6170b404f 103
nexpaq 1:55a6170b404f 104 mbedtls_x509_crt_init( &cert );
nexpaq 1:55a6170b404f 105
nexpaq 1:55a6170b404f 106 if( priv_key == NULL )
nexpaq 1:55a6170b404f 107 goto cleanup;
nexpaq 1:55a6170b404f 108
nexpaq 1:55a6170b404f 109 if( 0 != mbedtls_pkcs11_x509_cert_bind( &cert, pkcs11_cert ) )
nexpaq 1:55a6170b404f 110 goto cleanup;
nexpaq 1:55a6170b404f 111
nexpaq 1:55a6170b404f 112 priv_key->len = mbedtls_pk_get_len( &cert.pk );
nexpaq 1:55a6170b404f 113 priv_key->pkcs11h_cert = pkcs11_cert;
nexpaq 1:55a6170b404f 114
nexpaq 1:55a6170b404f 115 ret = 0;
nexpaq 1:55a6170b404f 116
nexpaq 1:55a6170b404f 117 cleanup:
nexpaq 1:55a6170b404f 118 mbedtls_x509_crt_free( &cert );
nexpaq 1:55a6170b404f 119
nexpaq 1:55a6170b404f 120 return( ret );
nexpaq 1:55a6170b404f 121 }
nexpaq 1:55a6170b404f 122
nexpaq 1:55a6170b404f 123 void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key )
nexpaq 1:55a6170b404f 124 {
nexpaq 1:55a6170b404f 125 if( NULL != priv_key )
nexpaq 1:55a6170b404f 126 pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
nexpaq 1:55a6170b404f 127 }
nexpaq 1:55a6170b404f 128
nexpaq 1:55a6170b404f 129 int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx,
nexpaq 1:55a6170b404f 130 int mode, size_t *olen,
nexpaq 1:55a6170b404f 131 const unsigned char *input,
nexpaq 1:55a6170b404f 132 unsigned char *output,
nexpaq 1:55a6170b404f 133 size_t output_max_len )
nexpaq 1:55a6170b404f 134 {
nexpaq 1:55a6170b404f 135 size_t input_len, output_len;
nexpaq 1:55a6170b404f 136
nexpaq 1:55a6170b404f 137 if( NULL == ctx )
nexpaq 1:55a6170b404f 138 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
nexpaq 1:55a6170b404f 139
nexpaq 1:55a6170b404f 140 if( MBEDTLS_RSA_PRIVATE != mode )
nexpaq 1:55a6170b404f 141 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
nexpaq 1:55a6170b404f 142
nexpaq 1:55a6170b404f 143 output_len = input_len = ctx->len;
nexpaq 1:55a6170b404f 144
nexpaq 1:55a6170b404f 145 if( input_len < 16 || input_len > output_max_len )
nexpaq 1:55a6170b404f 146 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
nexpaq 1:55a6170b404f 147
nexpaq 1:55a6170b404f 148 /* Determine size of output buffer */
nexpaq 1:55a6170b404f 149 if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
nexpaq 1:55a6170b404f 150 input_len, NULL, &output_len ) != CKR_OK )
nexpaq 1:55a6170b404f 151 {
nexpaq 1:55a6170b404f 152 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
nexpaq 1:55a6170b404f 153 }
nexpaq 1:55a6170b404f 154
nexpaq 1:55a6170b404f 155 if( output_len > output_max_len )
nexpaq 1:55a6170b404f 156 return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
nexpaq 1:55a6170b404f 157
nexpaq 1:55a6170b404f 158 if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
nexpaq 1:55a6170b404f 159 input_len, output, &output_len ) != CKR_OK )
nexpaq 1:55a6170b404f 160 {
nexpaq 1:55a6170b404f 161 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
nexpaq 1:55a6170b404f 162 }
nexpaq 1:55a6170b404f 163 *olen = output_len;
nexpaq 1:55a6170b404f 164 return( 0 );
nexpaq 1:55a6170b404f 165 }
nexpaq 1:55a6170b404f 166
nexpaq 1:55a6170b404f 167 int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx,
nexpaq 1:55a6170b404f 168 int mode,
nexpaq 1:55a6170b404f 169 mbedtls_md_type_t md_alg,
nexpaq 1:55a6170b404f 170 unsigned int hashlen,
nexpaq 1:55a6170b404f 171 const unsigned char *hash,
nexpaq 1:55a6170b404f 172 unsigned char *sig )
nexpaq 1:55a6170b404f 173 {
nexpaq 1:55a6170b404f 174 size_t sig_len = 0, asn_len = 0, oid_size = 0;
nexpaq 1:55a6170b404f 175 unsigned char *p = sig;
nexpaq 1:55a6170b404f 176 const char *oid;
nexpaq 1:55a6170b404f 177
nexpaq 1:55a6170b404f 178 if( NULL == ctx )
nexpaq 1:55a6170b404f 179 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
nexpaq 1:55a6170b404f 180
nexpaq 1:55a6170b404f 181 if( MBEDTLS_RSA_PRIVATE != mode )
nexpaq 1:55a6170b404f 182 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
nexpaq 1:55a6170b404f 183
nexpaq 1:55a6170b404f 184 if( md_alg != MBEDTLS_MD_NONE )
nexpaq 1:55a6170b404f 185 {
nexpaq 1:55a6170b404f 186 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
nexpaq 1:55a6170b404f 187 if( md_info == NULL )
nexpaq 1:55a6170b404f 188 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
nexpaq 1:55a6170b404f 189
nexpaq 1:55a6170b404f 190 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
nexpaq 1:55a6170b404f 191 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
nexpaq 1:55a6170b404f 192
nexpaq 1:55a6170b404f 193 hashlen = mbedtls_md_get_size( md_info );
nexpaq 1:55a6170b404f 194 asn_len = 10 + oid_size;
nexpaq 1:55a6170b404f 195 }
nexpaq 1:55a6170b404f 196
nexpaq 1:55a6170b404f 197 sig_len = ctx->len;
nexpaq 1:55a6170b404f 198 if( hashlen > sig_len || asn_len > sig_len ||
nexpaq 1:55a6170b404f 199 hashlen + asn_len > sig_len )
nexpaq 1:55a6170b404f 200 {
nexpaq 1:55a6170b404f 201 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
nexpaq 1:55a6170b404f 202 }
nexpaq 1:55a6170b404f 203
nexpaq 1:55a6170b404f 204 if( md_alg != MBEDTLS_MD_NONE )
nexpaq 1:55a6170b404f 205 {
nexpaq 1:55a6170b404f 206 /*
nexpaq 1:55a6170b404f 207 * DigestInfo ::= SEQUENCE {
nexpaq 1:55a6170b404f 208 * digestAlgorithm DigestAlgorithmIdentifier,
nexpaq 1:55a6170b404f 209 * digest Digest }
nexpaq 1:55a6170b404f 210 *
nexpaq 1:55a6170b404f 211 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
nexpaq 1:55a6170b404f 212 *
nexpaq 1:55a6170b404f 213 * Digest ::= OCTET STRING
nexpaq 1:55a6170b404f 214 */
nexpaq 1:55a6170b404f 215 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
nexpaq 1:55a6170b404f 216 *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
nexpaq 1:55a6170b404f 217 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
nexpaq 1:55a6170b404f 218 *p++ = (unsigned char) ( 0x04 + oid_size );
nexpaq 1:55a6170b404f 219 *p++ = MBEDTLS_ASN1_OID;
nexpaq 1:55a6170b404f 220 *p++ = oid_size & 0xFF;
nexpaq 1:55a6170b404f 221 memcpy( p, oid, oid_size );
nexpaq 1:55a6170b404f 222 p += oid_size;
nexpaq 1:55a6170b404f 223 *p++ = MBEDTLS_ASN1_NULL;
nexpaq 1:55a6170b404f 224 *p++ = 0x00;
nexpaq 1:55a6170b404f 225 *p++ = MBEDTLS_ASN1_OCTET_STRING;
nexpaq 1:55a6170b404f 226 *p++ = hashlen;
nexpaq 1:55a6170b404f 227 }
nexpaq 1:55a6170b404f 228
nexpaq 1:55a6170b404f 229 memcpy( p, hash, hashlen );
nexpaq 1:55a6170b404f 230
nexpaq 1:55a6170b404f 231 if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
nexpaq 1:55a6170b404f 232 asn_len + hashlen, sig, &sig_len ) != CKR_OK )
nexpaq 1:55a6170b404f 233 {
nexpaq 1:55a6170b404f 234 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
nexpaq 1:55a6170b404f 235 }
nexpaq 1:55a6170b404f 236
nexpaq 1:55a6170b404f 237 return( 0 );
nexpaq 1:55a6170b404f 238 }
nexpaq 1:55a6170b404f 239
nexpaq 1:55a6170b404f 240 #endif /* defined(MBEDTLS_PKCS11_C) */