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