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 The Mbed TLS Contributors
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
51 #include "mbedtls/pkcs11.h"
52
53 #if defined(MBEDTLS_PKCS11_C)
54
55 #include "mbedtls/md.h"
56 #include "mbedtls/oid.h"
57 #include "mbedtls/x509_crt.h"
58
59 #if defined(MBEDTLS_PLATFORM_C)
60 #include "mbedtls/platform.h"
61 #else
62 #include <stdlib.h>
63 #define mbedtls_calloc calloc
64 #define mbedtls_free free
65 #endif
66
67 #include <string.h>
68
mbedtls_pkcs11_init(mbedtls_pkcs11_context * ctx)69 void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx )
70 {
71 memset( ctx, 0, sizeof( mbedtls_pkcs11_context ) );
72 }
73
mbedtls_pkcs11_x509_cert_bind(mbedtls_x509_crt * cert,pkcs11h_certificate_t pkcs11_cert)74 int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11_cert )
75 {
76 int ret = 1;
77 unsigned char *cert_blob = NULL;
78 size_t cert_blob_size = 0;
79
80 if( cert == NULL )
81 {
82 ret = 2;
83 goto cleanup;
84 }
85
86 if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL,
87 &cert_blob_size ) != CKR_OK )
88 {
89 ret = 3;
90 goto cleanup;
91 }
92
93 cert_blob = mbedtls_calloc( 1, cert_blob_size );
94 if( NULL == cert_blob )
95 {
96 ret = 4;
97 goto cleanup;
98 }
99
100 if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob,
101 &cert_blob_size ) != CKR_OK )
102 {
103 ret = 5;
104 goto cleanup;
105 }
106
107 if( 0 != mbedtls_x509_crt_parse( cert, cert_blob, cert_blob_size ) )
108 {
109 ret = 6;
110 goto cleanup;
111 }
112
113 ret = 0;
114
115 cleanup:
116 if( NULL != cert_blob )
117 mbedtls_free( cert_blob );
118
119 return( ret );
120 }
121
122
mbedtls_pkcs11_priv_key_bind(mbedtls_pkcs11_context * priv_key,pkcs11h_certificate_t pkcs11_cert)123 int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key,
124 pkcs11h_certificate_t pkcs11_cert )
125 {
126 int ret = 1;
127 mbedtls_x509_crt cert;
128
129 mbedtls_x509_crt_init( &cert );
130
131 if( priv_key == NULL )
132 goto cleanup;
133
134 if( 0 != mbedtls_pkcs11_x509_cert_bind( &cert, pkcs11_cert ) )
135 goto cleanup;
136
137 priv_key->len = mbedtls_pk_get_len( &cert.pk );
138 priv_key->pkcs11h_cert = pkcs11_cert;
139
140 ret = 0;
141
142 cleanup:
143 mbedtls_x509_crt_free( &cert );
144
145 return( ret );
146 }
147
mbedtls_pkcs11_priv_key_free(mbedtls_pkcs11_context * priv_key)148 void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key )
149 {
150 if( NULL != priv_key )
151 pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
152 }
153
mbedtls_pkcs11_decrypt(mbedtls_pkcs11_context * ctx,int mode,size_t * olen,const unsigned char * input,unsigned char * output,size_t output_max_len)154 int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx,
155 int mode, size_t *olen,
156 const unsigned char *input,
157 unsigned char *output,
158 size_t output_max_len )
159 {
160 size_t input_len, output_len;
161
162 if( NULL == ctx )
163 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
164
165 if( MBEDTLS_RSA_PRIVATE != mode )
166 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
167
168 output_len = input_len = ctx->len;
169
170 if( input_len < 16 || input_len > output_max_len )
171 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
172
173 /* Determine size of output buffer */
174 if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
175 input_len, NULL, &output_len ) != CKR_OK )
176 {
177 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
178 }
179
180 if( output_len > output_max_len )
181 return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
182
183 if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
184 input_len, output, &output_len ) != CKR_OK )
185 {
186 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
187 }
188 *olen = output_len;
189 return( 0 );
190 }
191
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)192 int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx,
193 int mode,
194 mbedtls_md_type_t md_alg,
195 unsigned int hashlen,
196 const unsigned char *hash,
197 unsigned char *sig )
198 {
199 size_t sig_len = 0, asn_len = 0, oid_size = 0;
200 unsigned char *p = sig;
201 const char *oid;
202
203 if( NULL == ctx )
204 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
205
206 if( MBEDTLS_RSA_PRIVATE != mode )
207 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
208
209 if( md_alg != MBEDTLS_MD_NONE )
210 {
211 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
212 if( md_info == NULL )
213 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
214
215 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
216 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
217
218 hashlen = mbedtls_md_get_size( md_info );
219 asn_len = 10 + oid_size;
220 }
221
222 sig_len = ctx->len;
223 if( hashlen > sig_len || asn_len > sig_len ||
224 hashlen + asn_len > sig_len )
225 {
226 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
227 }
228
229 if( md_alg != MBEDTLS_MD_NONE )
230 {
231 /*
232 * DigestInfo ::= SEQUENCE {
233 * digestAlgorithm DigestAlgorithmIdentifier,
234 * digest Digest }
235 *
236 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
237 *
238 * Digest ::= OCTET STRING
239 */
240 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
241 *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
242 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
243 *p++ = (unsigned char) ( 0x04 + oid_size );
244 *p++ = MBEDTLS_ASN1_OID;
245 *p++ = oid_size & 0xFF;
246 memcpy( p, oid, oid_size );
247 p += oid_size;
248 *p++ = MBEDTLS_ASN1_NULL;
249 *p++ = 0x00;
250 *p++ = MBEDTLS_ASN1_OCTET_STRING;
251 *p++ = hashlen;
252 }
253
254 memcpy( p, hash, hashlen );
255
256 if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
257 asn_len + hashlen, sig, &sig_len ) != CKR_OK )
258 {
259 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
260 }
261
262 return( 0 );
263 }
264
265 #endif /* defined(MBEDTLS_PKCS11_C) */
266