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: Apache-2.0 OR GPL-2.0-or-later 10 * 11 * This file is provided under the Apache License 2.0, or the 12 * GNU General Public License v2.0 or later. 13 * 14 * ********** 15 * Apache License 2.0: 16 * 17 * Licensed under the Apache License, Version 2.0 (the "License"); you may 18 * not use this file except in compliance with the License. 19 * You may obtain a copy of the License at 20 * 21 * http://www.apache.org/licenses/LICENSE-2.0 22 * 23 * Unless required by applicable law or agreed to in writing, software 24 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 25 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26 * See the License for the specific language governing permissions and 27 * limitations under the License. 28 * 29 * ********** 30 * 31 * ********** 32 * GNU General Public License v2.0 or later: 33 * 34 * This program is free software; you can redistribute it and/or modify 35 * it under the terms of the GNU General Public License as published by 36 * the Free Software Foundation; either version 2 of the License, or 37 * (at your option) any later version. 38 * 39 * This program is distributed in the hope that it will be useful, 40 * but WITHOUT ANY WARRANTY; without even the implied warranty of 41 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 42 * GNU General Public License for more details. 43 * 44 * You should have received a copy of the GNU General Public License along 45 * with this program; if not, write to the Free Software Foundation, Inc., 46 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 47 * 48 * ********** 49 * 50 * This file is part of mbed TLS (https://tls.mbed.org) 51 */ 52 53 #include "mbedtls/pkcs11.h" 54 55 #if defined(MBEDTLS_PKCS11_C) 56 57 #include "mbedtls/md.h" 58 #include "mbedtls/oid.h" 59 #include "mbedtls/x509_crt.h" 60 61 #if defined(MBEDTLS_PLATFORM_C) 62 #include "mbedtls/platform.h" 63 #else 64 #include <stdlib.h> 65 #define mbedtls_calloc calloc 66 #define mbedtls_free free 67 #endif 68 69 #include <string.h> 70 71 void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx ) 72 { 73 memset( ctx, 0, sizeof( mbedtls_pkcs11_context ) ); 74 } 75 76 int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11_cert ) 77 { 78 int ret = 1; 79 unsigned char *cert_blob = NULL; 80 size_t cert_blob_size = 0; 81 82 if( cert == NULL ) 83 { 84 ret = 2; 85 goto cleanup; 86 } 87 88 if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL, 89 &cert_blob_size ) != CKR_OK ) 90 { 91 ret = 3; 92 goto cleanup; 93 } 94 95 cert_blob = mbedtls_calloc( 1, cert_blob_size ); 96 if( NULL == cert_blob ) 97 { 98 ret = 4; 99 goto cleanup; 100 } 101 102 if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob, 103 &cert_blob_size ) != CKR_OK ) 104 { 105 ret = 5; 106 goto cleanup; 107 } 108 109 if( 0 != mbedtls_x509_crt_parse( cert, cert_blob, cert_blob_size ) ) 110 { 111 ret = 6; 112 goto cleanup; 113 } 114 115 ret = 0; 116 117 cleanup: 118 if( NULL != cert_blob ) 119 mbedtls_free( cert_blob ); 120 121 return( ret ); 122 } 123 124 125 int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key, 126 pkcs11h_certificate_t pkcs11_cert ) 127 { 128 int ret = 1; 129 mbedtls_x509_crt cert; 130 131 mbedtls_x509_crt_init( &cert ); 132 133 if( priv_key == NULL ) 134 goto cleanup; 135 136 if( 0 != mbedtls_pkcs11_x509_cert_bind( &cert, pkcs11_cert ) ) 137 goto cleanup; 138 139 priv_key->len = mbedtls_pk_get_len( &cert.pk ); 140 priv_key->pkcs11h_cert = pkcs11_cert; 141 142 ret = 0; 143 144 cleanup: 145 mbedtls_x509_crt_free( &cert ); 146 147 return( ret ); 148 } 149 150 void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key ) 151 { 152 if( NULL != priv_key ) 153 pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert ); 154 } 155 156 int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx, 157 int mode, size_t *olen, 158 const unsigned char *input, 159 unsigned char *output, 160 size_t output_max_len ) 161 { 162 size_t input_len, output_len; 163 164 if( NULL == ctx ) 165 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 166 167 if( MBEDTLS_RSA_PRIVATE != mode ) 168 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 169 170 output_len = input_len = ctx->len; 171 172 if( input_len < 16 || input_len > output_max_len ) 173 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 174 175 /* Determine size of output buffer */ 176 if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, 177 input_len, NULL, &output_len ) != CKR_OK ) 178 { 179 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 180 } 181 182 if( output_len > output_max_len ) 183 return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); 184 185 if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, 186 input_len, output, &output_len ) != CKR_OK ) 187 { 188 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 189 } 190 *olen = output_len; 191 return( 0 ); 192 } 193 194 int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx, 195 int mode, 196 mbedtls_md_type_t md_alg, 197 unsigned int hashlen, 198 const unsigned char *hash, 199 unsigned char *sig ) 200 { 201 size_t sig_len = 0, asn_len = 0, oid_size = 0; 202 unsigned char *p = sig; 203 const char *oid; 204 205 if( NULL == ctx ) 206 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 207 208 if( MBEDTLS_RSA_PRIVATE != mode ) 209 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 210 211 if( md_alg != MBEDTLS_MD_NONE ) 212 { 213 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); 214 if( md_info == NULL ) 215 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 216 217 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) 218 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 219 220 hashlen = mbedtls_md_get_size( md_info ); 221 asn_len = 10 + oid_size; 222 } 223 224 sig_len = ctx->len; 225 if( hashlen > sig_len || asn_len > sig_len || 226 hashlen + asn_len > sig_len ) 227 { 228 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 229 } 230 231 if( md_alg != MBEDTLS_MD_NONE ) 232 { 233 /* 234 * DigestInfo ::= SEQUENCE { 235 * digestAlgorithm DigestAlgorithmIdentifier, 236 * digest Digest } 237 * 238 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier 239 * 240 * Digest ::= OCTET STRING 241 */ 242 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; 243 *p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); 244 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; 245 *p++ = (unsigned char) ( 0x04 + oid_size ); 246 *p++ = MBEDTLS_ASN1_OID; 247 *p++ = oid_size & 0xFF; 248 memcpy( p, oid, oid_size ); 249 p += oid_size; 250 *p++ = MBEDTLS_ASN1_NULL; 251 *p++ = 0x00; 252 *p++ = MBEDTLS_ASN1_OCTET_STRING; 253 *p++ = hashlen; 254 } 255 256 memcpy( p, hash, hashlen ); 257 258 if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig, 259 asn_len + hashlen, sig, &sig_len ) != CKR_OK ) 260 { 261 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 262 } 263 264 return( 0 ); 265 } 266 267 #endif /* defined(MBEDTLS_PKCS11_C) */ 268