4 * \brief Wrapper for PKCS#11 library libpkcs11-helper
6 * \author Adriaan de Jong <dejong@fox-it.com>
8 * Copyright The Mbed TLS Contributors
9 * SPDX-License-Identifier: Apache-2.0
11 * Licensed under the Apache License, Version 2.0 (the "License"); you may
12 * not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
19 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
24 #include "mbedtls/pkcs11.h"
26 #if defined(MBEDTLS_PKCS11_C)
28 #include "mbedtls/md.h"
29 #include "mbedtls/oid.h"
30 #include "mbedtls/x509_crt.h"
32 #if defined(MBEDTLS_PLATFORM_C)
33 #include "mbedtls/platform.h"
36 #define mbedtls_calloc calloc
37 #define mbedtls_free free
42 void mbedtls_pkcs11_init(mbedtls_pkcs11_context
*ctx
) {
43 memset(ctx
, 0, sizeof(mbedtls_pkcs11_context
));
46 int mbedtls_pkcs11_x509_cert_bind(mbedtls_x509_crt
*cert
, pkcs11h_certificate_t pkcs11_cert
) {
48 unsigned char *cert_blob
= NULL
;
49 size_t cert_blob_size
= 0;
56 if (pkcs11h_certificate_getCertificateBlob(pkcs11_cert
, NULL
,
57 &cert_blob_size
) != CKR_OK
) {
62 cert_blob
= mbedtls_calloc(1, cert_blob_size
);
63 if (NULL
== cert_blob
) {
68 if (pkcs11h_certificate_getCertificateBlob(pkcs11_cert
, cert_blob
,
69 &cert_blob_size
) != CKR_OK
) {
74 if (0 != mbedtls_x509_crt_parse(cert
, cert_blob
, cert_blob_size
)) {
82 if (NULL
!= cert_blob
)
83 mbedtls_free(cert_blob
);
89 int mbedtls_pkcs11_priv_key_bind(mbedtls_pkcs11_context
*priv_key
,
90 pkcs11h_certificate_t pkcs11_cert
) {
92 mbedtls_x509_crt cert
;
94 mbedtls_x509_crt_init(&cert
);
99 if (0 != mbedtls_pkcs11_x509_cert_bind(&cert
, pkcs11_cert
))
102 priv_key
->len
= mbedtls_pk_get_len(&cert
.pk
);
103 priv_key
->pkcs11h_cert
= pkcs11_cert
;
108 mbedtls_x509_crt_free(&cert
);
113 void mbedtls_pkcs11_priv_key_free(mbedtls_pkcs11_context
*priv_key
) {
114 if (NULL
!= priv_key
)
115 pkcs11h_certificate_freeCertificate(priv_key
->pkcs11h_cert
);
118 int mbedtls_pkcs11_decrypt(mbedtls_pkcs11_context
*ctx
,
119 int mode
, size_t *olen
,
120 const unsigned char *input
,
121 unsigned char *output
,
122 size_t output_max_len
) {
123 size_t input_len
, output_len
;
126 return (MBEDTLS_ERR_RSA_BAD_INPUT_DATA
);
128 if (MBEDTLS_RSA_PRIVATE
!= mode
)
129 return (MBEDTLS_ERR_RSA_BAD_INPUT_DATA
);
131 output_len
= input_len
= ctx
->len
;
133 if (input_len
< 16 || input_len
> output_max_len
)
134 return (MBEDTLS_ERR_RSA_BAD_INPUT_DATA
);
136 /* Determine size of output buffer */
137 if (pkcs11h_certificate_decryptAny(ctx
->pkcs11h_cert
, CKM_RSA_PKCS
, input
,
138 input_len
, NULL
, &output_len
) != CKR_OK
) {
139 return (MBEDTLS_ERR_RSA_BAD_INPUT_DATA
);
142 if (output_len
> output_max_len
)
143 return (MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
);
145 if (pkcs11h_certificate_decryptAny(ctx
->pkcs11h_cert
, CKM_RSA_PKCS
, input
,
146 input_len
, output
, &output_len
) != CKR_OK
) {
147 return (MBEDTLS_ERR_RSA_BAD_INPUT_DATA
);
153 int mbedtls_pkcs11_sign(mbedtls_pkcs11_context
*ctx
,
155 mbedtls_md_type_t md_alg
,
156 unsigned int hashlen
,
157 const unsigned char *hash
,
158 unsigned char *sig
) {
159 size_t sig_len
= 0, asn_len
= 0, oid_size
= 0;
160 unsigned char *p
= sig
;
164 return (MBEDTLS_ERR_RSA_BAD_INPUT_DATA
);
166 if (MBEDTLS_RSA_PRIVATE
!= mode
)
167 return (MBEDTLS_ERR_RSA_BAD_INPUT_DATA
);
169 if (md_alg
!= MBEDTLS_MD_NONE
) {
170 const mbedtls_md_info_t
*md_info
= mbedtls_md_info_from_type(md_alg
);
172 return (MBEDTLS_ERR_RSA_BAD_INPUT_DATA
);
174 if (mbedtls_oid_get_oid_by_md(md_alg
, &oid
, &oid_size
) != 0)
175 return (MBEDTLS_ERR_RSA_BAD_INPUT_DATA
);
177 hashlen
= mbedtls_md_get_size(md_info
);
178 asn_len
= 10 + oid_size
;
182 if (hashlen
> sig_len
|| asn_len
> sig_len
||
183 hashlen
+ asn_len
> sig_len
) {
184 return (MBEDTLS_ERR_RSA_BAD_INPUT_DATA
);
187 if (md_alg
!= MBEDTLS_MD_NONE
) {
189 * DigestInfo ::= SEQUENCE {
190 * digestAlgorithm DigestAlgorithmIdentifier,
193 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
195 * Digest ::= OCTET STRING
197 *p
++ = MBEDTLS_ASN1_SEQUENCE
| MBEDTLS_ASN1_CONSTRUCTED
;
198 *p
++ = (unsigned char)(0x08 + oid_size
+ hashlen
);
199 *p
++ = MBEDTLS_ASN1_SEQUENCE
| MBEDTLS_ASN1_CONSTRUCTED
;
200 *p
++ = (unsigned char)(0x04 + oid_size
);
201 *p
++ = MBEDTLS_ASN1_OID
;
202 *p
++ = oid_size
& 0xFF;
203 memcpy(p
, oid
, oid_size
);
205 *p
++ = MBEDTLS_ASN1_NULL
;
207 *p
++ = MBEDTLS_ASN1_OCTET_STRING
;
211 memcpy(p
, hash
, hashlen
);
213 if (pkcs11h_certificate_signAny(ctx
->pkcs11h_cert
, CKM_RSA_PKCS
, sig
,
214 asn_len
+ hashlen
, sig
, &sig_len
) != CKR_OK
) {
215 return (MBEDTLS_ERR_RSA_BAD_INPUT_DATA
);
221 #endif /* defined(MBEDTLS_PKCS11_C) */