1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2023 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker */
5*8617a60dSAndroid Build Coastguard Worker
6*8617a60dSAndroid Build Coastguard Worker #include <stdio.h>
7*8617a60dSAndroid Build Coastguard Worker #include <stdlib.h>
8*8617a60dSAndroid Build Coastguard Worker #include <sys/types.h>
9*8617a60dSAndroid Build Coastguard Worker #include <unistd.h>
10*8617a60dSAndroid Build Coastguard Worker #include <dlfcn.h>
11*8617a60dSAndroid Build Coastguard Worker
12*8617a60dSAndroid Build Coastguard Worker #include <pkcs11.h>
13*8617a60dSAndroid Build Coastguard Worker
14*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
15*8617a60dSAndroid Build Coastguard Worker #include "host_p11.h"
16*8617a60dSAndroid Build Coastguard Worker #include "vboot_host.h"
17*8617a60dSAndroid Build Coastguard Worker #include "util_misc.h"
18*8617a60dSAndroid Build Coastguard Worker
19*8617a60dSAndroid Build Coastguard Worker struct pkcs11_key {
20*8617a60dSAndroid Build Coastguard Worker CK_OBJECT_HANDLE handle;
21*8617a60dSAndroid Build Coastguard Worker CK_SESSION_HANDLE session;
22*8617a60dSAndroid Build Coastguard Worker };
23*8617a60dSAndroid Build Coastguard Worker
24*8617a60dSAndroid Build Coastguard Worker // We only maintain one global p11 module at a time.
25*8617a60dSAndroid Build Coastguard Worker static CK_FUNCTION_LIST_PTR p11 = NULL;
26*8617a60dSAndroid Build Coastguard Worker
pkcs11_load(const char * mspec,CK_FUNCTION_LIST_PTR_PTR funcs)27*8617a60dSAndroid Build Coastguard Worker static void *pkcs11_load(const char *mspec, CK_FUNCTION_LIST_PTR_PTR funcs)
28*8617a60dSAndroid Build Coastguard Worker {
29*8617a60dSAndroid Build Coastguard Worker void *mod;
30*8617a60dSAndroid Build Coastguard Worker CK_RV rv;
31*8617a60dSAndroid Build Coastguard Worker CK_RV (*c_get_function_list)(CK_FUNCTION_LIST_PTR_PTR p11);
32*8617a60dSAndroid Build Coastguard Worker
33*8617a60dSAndroid Build Coastguard Worker if (mspec == NULL)
34*8617a60dSAndroid Build Coastguard Worker return NULL;
35*8617a60dSAndroid Build Coastguard Worker
36*8617a60dSAndroid Build Coastguard Worker mod = dlopen(mspec, RTLD_LAZY);
37*8617a60dSAndroid Build Coastguard Worker if (mod == NULL) {
38*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "dlopen failed: %s\n", dlerror());
39*8617a60dSAndroid Build Coastguard Worker return NULL;
40*8617a60dSAndroid Build Coastguard Worker }
41*8617a60dSAndroid Build Coastguard Worker
42*8617a60dSAndroid Build Coastguard Worker /* Get the list of function pointers */
43*8617a60dSAndroid Build Coastguard Worker c_get_function_list =
44*8617a60dSAndroid Build Coastguard Worker (CK_RV(*)(CK_FUNCTION_LIST_PTR_PTR))dlsym(mod, "C_GetFunctionList");
45*8617a60dSAndroid Build Coastguard Worker if (!c_get_function_list)
46*8617a60dSAndroid Build Coastguard Worker goto err;
47*8617a60dSAndroid Build Coastguard Worker rv = c_get_function_list(funcs);
48*8617a60dSAndroid Build Coastguard Worker if (rv == CKR_OK)
49*8617a60dSAndroid Build Coastguard Worker return mod;
50*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "C_GetFunctionList failed 0x%lx", rv);
51*8617a60dSAndroid Build Coastguard Worker err:
52*8617a60dSAndroid Build Coastguard Worker dlclose(mod);
53*8617a60dSAndroid Build Coastguard Worker return NULL;
54*8617a60dSAndroid Build Coastguard Worker }
55*8617a60dSAndroid Build Coastguard Worker
pkcs11_find(CK_SESSION_HANDLE session,CK_ATTRIBUTE attributes[],CK_ULONG num_attributes,CK_OBJECT_HANDLE * object)56*8617a60dSAndroid Build Coastguard Worker static vb2_error_t pkcs11_find(CK_SESSION_HANDLE session, CK_ATTRIBUTE attributes[],
57*8617a60dSAndroid Build Coastguard Worker CK_ULONG num_attributes, CK_OBJECT_HANDLE *object)
58*8617a60dSAndroid Build Coastguard Worker {
59*8617a60dSAndroid Build Coastguard Worker CK_RV result = p11->C_FindObjectsInit(session, attributes, num_attributes);
60*8617a60dSAndroid Build Coastguard Worker if (result != CKR_OK)
61*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
62*8617a60dSAndroid Build Coastguard Worker
63*8617a60dSAndroid Build Coastguard Worker CK_ULONG object_count = 1;
64*8617a60dSAndroid Build Coastguard Worker result = p11->C_FindObjects(session, object, 1, &object_count);
65*8617a60dSAndroid Build Coastguard Worker if (result != CKR_OK || object_count == 0)
66*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
67*8617a60dSAndroid Build Coastguard Worker
68*8617a60dSAndroid Build Coastguard Worker result = p11->C_FindObjectsFinal(session);
69*8617a60dSAndroid Build Coastguard Worker if (result != CKR_OK)
70*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
71*8617a60dSAndroid Build Coastguard Worker
72*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
73*8617a60dSAndroid Build Coastguard Worker }
74*8617a60dSAndroid Build Coastguard Worker
75*8617a60dSAndroid Build Coastguard Worker static enum vb2_hash_algorithm
pkcs11_mechanism_type_to_hash_alg(CK_MECHANISM_TYPE p11_mechanism)76*8617a60dSAndroid Build Coastguard Worker pkcs11_mechanism_type_to_hash_alg(CK_MECHANISM_TYPE p11_mechanism)
77*8617a60dSAndroid Build Coastguard Worker {
78*8617a60dSAndroid Build Coastguard Worker switch (p11_mechanism) {
79*8617a60dSAndroid Build Coastguard Worker case CKM_SHA1_RSA_PKCS:
80*8617a60dSAndroid Build Coastguard Worker return VB2_HASH_SHA1;
81*8617a60dSAndroid Build Coastguard Worker case CKM_SHA256_RSA_PKCS:
82*8617a60dSAndroid Build Coastguard Worker return VB2_HASH_SHA256;
83*8617a60dSAndroid Build Coastguard Worker case CKM_SHA512_RSA_PKCS:
84*8617a60dSAndroid Build Coastguard Worker return VB2_HASH_SHA512;
85*8617a60dSAndroid Build Coastguard Worker }
86*8617a60dSAndroid Build Coastguard Worker return VB2_HASH_INVALID;
87*8617a60dSAndroid Build Coastguard Worker }
88*8617a60dSAndroid Build Coastguard Worker
pkcs11_init(const char * pkcs11_lib)89*8617a60dSAndroid Build Coastguard Worker vb2_error_t pkcs11_init(const char *pkcs11_lib)
90*8617a60dSAndroid Build Coastguard Worker {
91*8617a60dSAndroid Build Coastguard Worker static char *loaded_pkcs11_lib = NULL;
92*8617a60dSAndroid Build Coastguard Worker static void *pkcs11_mod = NULL;
93*8617a60dSAndroid Build Coastguard Worker if (pkcs11_lib == NULL) {
94*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Missing the path of pkcs11 library\n");
95*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
96*8617a60dSAndroid Build Coastguard Worker }
97*8617a60dSAndroid Build Coastguard Worker if (loaded_pkcs11_lib) {
98*8617a60dSAndroid Build Coastguard Worker /* Return success if the same pkcs11 library is already loaded */
99*8617a60dSAndroid Build Coastguard Worker if (strcmp(loaded_pkcs11_lib, pkcs11_lib) == 0)
100*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
101*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Pkcs11 module is already loaded\n");
102*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
103*8617a60dSAndroid Build Coastguard Worker }
104*8617a60dSAndroid Build Coastguard Worker
105*8617a60dSAndroid Build Coastguard Worker pkcs11_mod = pkcs11_load(pkcs11_lib, &p11);
106*8617a60dSAndroid Build Coastguard Worker if (pkcs11_mod == NULL) {
107*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to load pkcs11 library '%s'\n", pkcs11_lib);
108*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
109*8617a60dSAndroid Build Coastguard Worker }
110*8617a60dSAndroid Build Coastguard Worker
111*8617a60dSAndroid Build Coastguard Worker CK_RV result = p11->C_Initialize(NULL);
112*8617a60dSAndroid Build Coastguard Worker if (result != CKR_OK) {
113*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to C_Initialize\n");
114*8617a60dSAndroid Build Coastguard Worker dlclose(pkcs11_mod);
115*8617a60dSAndroid Build Coastguard Worker pkcs11_mod = NULL;
116*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
117*8617a60dSAndroid Build Coastguard Worker }
118*8617a60dSAndroid Build Coastguard Worker loaded_pkcs11_lib = strdup(pkcs11_lib);
119*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
120*8617a60dSAndroid Build Coastguard Worker }
121*8617a60dSAndroid Build Coastguard Worker
pkcs11_get_key(int slot_id,char * label)122*8617a60dSAndroid Build Coastguard Worker struct pkcs11_key *pkcs11_get_key(int slot_id, char *label)
123*8617a60dSAndroid Build Coastguard Worker {
124*8617a60dSAndroid Build Coastguard Worker if (!p11) {
125*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "pkcs11 is not loaded\n");
126*8617a60dSAndroid Build Coastguard Worker return NULL;
127*8617a60dSAndroid Build Coastguard Worker }
128*8617a60dSAndroid Build Coastguard Worker
129*8617a60dSAndroid Build Coastguard Worker struct pkcs11_key *p11_key = malloc(sizeof(struct pkcs11_key));
130*8617a60dSAndroid Build Coastguard Worker if (!p11_key) {
131*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to allocate pkcs11 key\n");
132*8617a60dSAndroid Build Coastguard Worker return NULL;
133*8617a60dSAndroid Build Coastguard Worker }
134*8617a60dSAndroid Build Coastguard Worker
135*8617a60dSAndroid Build Coastguard Worker CK_RV result = p11->C_OpenSession(slot_id, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL,
136*8617a60dSAndroid Build Coastguard Worker NULL, &p11_key->session);
137*8617a60dSAndroid Build Coastguard Worker
138*8617a60dSAndroid Build Coastguard Worker if (result != CKR_OK) {
139*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to open session with slot id %d\n", slot_id);
140*8617a60dSAndroid Build Coastguard Worker free(p11_key);
141*8617a60dSAndroid Build Coastguard Worker return NULL;
142*8617a60dSAndroid Build Coastguard Worker }
143*8617a60dSAndroid Build Coastguard Worker
144*8617a60dSAndroid Build Coastguard Worker /* Find the private key */
145*8617a60dSAndroid Build Coastguard Worker CK_OBJECT_CLASS class_value = CKO_PRIVATE_KEY;
146*8617a60dSAndroid Build Coastguard Worker CK_ATTRIBUTE attributes[] = {
147*8617a60dSAndroid Build Coastguard Worker {CKA_CLASS, &class_value, sizeof(class_value)},
148*8617a60dSAndroid Build Coastguard Worker {CKA_LABEL, label, strlen(label)},
149*8617a60dSAndroid Build Coastguard Worker };
150*8617a60dSAndroid Build Coastguard Worker if (pkcs11_find(p11_key->session, attributes, ARRAY_SIZE(attributes),
151*8617a60dSAndroid Build Coastguard Worker &p11_key->handle) != VB2_SUCCESS) {
152*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to find the key with label '%s'\n", label);
153*8617a60dSAndroid Build Coastguard Worker pkcs11_free_key(p11_key);
154*8617a60dSAndroid Build Coastguard Worker return NULL;
155*8617a60dSAndroid Build Coastguard Worker }
156*8617a60dSAndroid Build Coastguard Worker
157*8617a60dSAndroid Build Coastguard Worker return p11_key;
158*8617a60dSAndroid Build Coastguard Worker }
159*8617a60dSAndroid Build Coastguard Worker
pkcs11_get_hash_alg(struct pkcs11_key * p11_key)160*8617a60dSAndroid Build Coastguard Worker enum vb2_hash_algorithm pkcs11_get_hash_alg(struct pkcs11_key *p11_key)
161*8617a60dSAndroid Build Coastguard Worker {
162*8617a60dSAndroid Build Coastguard Worker /* For PKCS#11 modules that support CKA_ALLOWED_MECHANISMS, we'll use the attribute
163*8617a60dSAndroid Build Coastguard Worker * to determine the correct mechanism to use. However, not all PKCS#11 modules
164*8617a60dSAndroid Build Coastguard Worker * support CKA_ALLOWED_MECHANISMS. In the event that we need to support such a
165*8617a60dSAndroid Build Coastguard Worker * module, we'll then need to determine the the mechanism to use from the key type
166*8617a60dSAndroid Build Coastguard Worker * and key size. That probably involves assuming we'll use PKCS#1 v1.5 padding for
167*8617a60dSAndroid Build Coastguard Worker * RSA. */
168*8617a60dSAndroid Build Coastguard Worker CK_ATTRIBUTE mechanism_attr = {CKA_ALLOWED_MECHANISMS, NULL, 0};
169*8617a60dSAndroid Build Coastguard Worker if (p11->C_GetAttributeValue(p11_key->session, p11_key->handle, &mechanism_attr, 1) !=
170*8617a60dSAndroid Build Coastguard Worker CKR_OK) {
171*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to get mechanisum attribute length\n");
172*8617a60dSAndroid Build Coastguard Worker return VB2_HASH_INVALID;
173*8617a60dSAndroid Build Coastguard Worker }
174*8617a60dSAndroid Build Coastguard Worker mechanism_attr.pValue = malloc(mechanism_attr.ulValueLen);
175*8617a60dSAndroid Build Coastguard Worker if (p11->C_GetAttributeValue(p11_key->session, p11_key->handle, &mechanism_attr, 1) !=
176*8617a60dSAndroid Build Coastguard Worker CKR_OK) {
177*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to get mechanisum attribute value\n");
178*8617a60dSAndroid Build Coastguard Worker free(mechanism_attr.pValue);
179*8617a60dSAndroid Build Coastguard Worker return VB2_HASH_INVALID;
180*8617a60dSAndroid Build Coastguard Worker }
181*8617a60dSAndroid Build Coastguard Worker CK_MECHANISM_TYPE *mechanisms = mechanism_attr.pValue;
182*8617a60dSAndroid Build Coastguard Worker uint32_t mechanism_count = mechanism_attr.ulValueLen / sizeof(CK_MECHANISM_TYPE);
183*8617a60dSAndroid Build Coastguard Worker enum vb2_hash_algorithm hash_alg = VB2_HASH_INVALID;
184*8617a60dSAndroid Build Coastguard Worker for (int i = 0; i < mechanism_count; ++i) {
185*8617a60dSAndroid Build Coastguard Worker hash_alg = pkcs11_mechanism_type_to_hash_alg(mechanisms[i]);
186*8617a60dSAndroid Build Coastguard Worker if (hash_alg != VB2_HASH_INVALID)
187*8617a60dSAndroid Build Coastguard Worker break;
188*8617a60dSAndroid Build Coastguard Worker }
189*8617a60dSAndroid Build Coastguard Worker free(mechanism_attr.pValue);
190*8617a60dSAndroid Build Coastguard Worker return hash_alg;
191*8617a60dSAndroid Build Coastguard Worker }
192*8617a60dSAndroid Build Coastguard Worker
pkcs11_get_sig_alg(struct pkcs11_key * p11_key)193*8617a60dSAndroid Build Coastguard Worker enum vb2_signature_algorithm pkcs11_get_sig_alg(struct pkcs11_key *p11_key)
194*8617a60dSAndroid Build Coastguard Worker {
195*8617a60dSAndroid Build Coastguard Worker if (!p11) {
196*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "pkcs11 is not loaded\n");
197*8617a60dSAndroid Build Coastguard Worker return VB2_SIG_INVALID;
198*8617a60dSAndroid Build Coastguard Worker }
199*8617a60dSAndroid Build Coastguard Worker CK_ULONG modulus_bits = 0;
200*8617a60dSAndroid Build Coastguard Worker CK_ATTRIBUTE modulus_attr = {CKA_MODULUS_BITS, &modulus_bits, sizeof(modulus_bits)};
201*8617a60dSAndroid Build Coastguard Worker if (p11->C_GetAttributeValue(p11_key->session, p11_key->handle, &modulus_attr, 1) !=
202*8617a60dSAndroid Build Coastguard Worker CKR_OK) {
203*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to get modulus bits\n");
204*8617a60dSAndroid Build Coastguard Worker return VB2_SIG_INVALID;
205*8617a60dSAndroid Build Coastguard Worker }
206*8617a60dSAndroid Build Coastguard Worker
207*8617a60dSAndroid Build Coastguard Worker CK_ATTRIBUTE exponent_attr = {CKA_PUBLIC_EXPONENT, NULL, 0};
208*8617a60dSAndroid Build Coastguard Worker if (p11->C_GetAttributeValue(p11_key->session, p11_key->handle, &exponent_attr, 1) !=
209*8617a60dSAndroid Build Coastguard Worker CKR_OK) {
210*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to get exponent attribute length\n");
211*8617a60dSAndroid Build Coastguard Worker return VB2_SIG_INVALID;
212*8617a60dSAndroid Build Coastguard Worker }
213*8617a60dSAndroid Build Coastguard Worker CK_ULONG exp_size = exponent_attr.ulValueLen;
214*8617a60dSAndroid Build Coastguard Worker if (exp_size > 4) {
215*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Exponent size is too large\n");
216*8617a60dSAndroid Build Coastguard Worker return VB2_SIG_INVALID;
217*8617a60dSAndroid Build Coastguard Worker }
218*8617a60dSAndroid Build Coastguard Worker exponent_attr.pValue = malloc(exp_size);
219*8617a60dSAndroid Build Coastguard Worker if (p11->C_GetAttributeValue(p11_key->session, p11_key->handle, &exponent_attr, 1) !=
220*8617a60dSAndroid Build Coastguard Worker CKR_OK) {
221*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to get exponent attribute value\n");
222*8617a60dSAndroid Build Coastguard Worker free(exponent_attr.pValue);
223*8617a60dSAndroid Build Coastguard Worker return VB2_SIG_INVALID;
224*8617a60dSAndroid Build Coastguard Worker }
225*8617a60dSAndroid Build Coastguard Worker // Parse the CKA_PUBLIC_EXPONENT in Big-endian.
226*8617a60dSAndroid Build Coastguard Worker CK_BYTE *exp_value = exponent_attr.pValue;
227*8617a60dSAndroid Build Coastguard Worker uint32_t exp = 0;
228*8617a60dSAndroid Build Coastguard Worker for (int i = 0; i < exp_size; ++i)
229*8617a60dSAndroid Build Coastguard Worker exp = (exp << 8) + exp_value[i];
230*8617a60dSAndroid Build Coastguard Worker free(exponent_attr.pValue);
231*8617a60dSAndroid Build Coastguard Worker
232*8617a60dSAndroid Build Coastguard Worker return vb2_get_sig_alg(exp, modulus_bits);
233*8617a60dSAndroid Build Coastguard Worker }
234*8617a60dSAndroid Build Coastguard Worker
pkcs11_get_modulus(struct pkcs11_key * p11_key,uint32_t * sizeptr)235*8617a60dSAndroid Build Coastguard Worker uint8_t *pkcs11_get_modulus(struct pkcs11_key *p11_key, uint32_t *sizeptr)
236*8617a60dSAndroid Build Coastguard Worker {
237*8617a60dSAndroid Build Coastguard Worker if (!p11) {
238*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "pkcs11 is not loaded\n");
239*8617a60dSAndroid Build Coastguard Worker return NULL;
240*8617a60dSAndroid Build Coastguard Worker }
241*8617a60dSAndroid Build Coastguard Worker CK_ATTRIBUTE modulus_attr = {CKA_MODULUS, NULL, 0};
242*8617a60dSAndroid Build Coastguard Worker if (p11->C_GetAttributeValue(p11_key->session, p11_key->handle, &modulus_attr, 1) !=
243*8617a60dSAndroid Build Coastguard Worker CKR_OK) {
244*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to get modulus attribute length\n");
245*8617a60dSAndroid Build Coastguard Worker return NULL;
246*8617a60dSAndroid Build Coastguard Worker }
247*8617a60dSAndroid Build Coastguard Worker CK_ULONG modulus_size = modulus_attr.ulValueLen;
248*8617a60dSAndroid Build Coastguard Worker modulus_attr.pValue = malloc(modulus_size);
249*8617a60dSAndroid Build Coastguard Worker if (p11->C_GetAttributeValue(p11_key->session, p11_key->handle, &modulus_attr, 1) !=
250*8617a60dSAndroid Build Coastguard Worker CKR_OK) {
251*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to get modulus attribute value\n");
252*8617a60dSAndroid Build Coastguard Worker free(modulus_attr.pValue);
253*8617a60dSAndroid Build Coastguard Worker return NULL;
254*8617a60dSAndroid Build Coastguard Worker }
255*8617a60dSAndroid Build Coastguard Worker *sizeptr = modulus_size;
256*8617a60dSAndroid Build Coastguard Worker return modulus_attr.pValue;
257*8617a60dSAndroid Build Coastguard Worker }
258*8617a60dSAndroid Build Coastguard Worker
pkcs11_sign(struct pkcs11_key * p11_key,enum vb2_hash_algorithm hash_alg,const uint8_t * data,int data_size,uint8_t * sig,uint32_t sig_size)259*8617a60dSAndroid Build Coastguard Worker vb2_error_t pkcs11_sign(struct pkcs11_key *p11_key, enum vb2_hash_algorithm hash_alg,
260*8617a60dSAndroid Build Coastguard Worker const uint8_t *data, int data_size, uint8_t *sig, uint32_t sig_size)
261*8617a60dSAndroid Build Coastguard Worker {
262*8617a60dSAndroid Build Coastguard Worker if (!p11) {
263*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "pkcs11 is not loaded\n");
264*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
265*8617a60dSAndroid Build Coastguard Worker }
266*8617a60dSAndroid Build Coastguard Worker
267*8617a60dSAndroid Build Coastguard Worker CK_MECHANISM mechanism;
268*8617a60dSAndroid Build Coastguard Worker switch (hash_alg) {
269*8617a60dSAndroid Build Coastguard Worker case VB2_HASH_SHA1:
270*8617a60dSAndroid Build Coastguard Worker mechanism.mechanism = CKM_SHA1_RSA_PKCS;
271*8617a60dSAndroid Build Coastguard Worker break;
272*8617a60dSAndroid Build Coastguard Worker case VB2_HASH_SHA256:
273*8617a60dSAndroid Build Coastguard Worker mechanism.mechanism = CKM_SHA256_RSA_PKCS;
274*8617a60dSAndroid Build Coastguard Worker break;
275*8617a60dSAndroid Build Coastguard Worker case VB2_HASH_SHA512:
276*8617a60dSAndroid Build Coastguard Worker mechanism.mechanism = CKM_SHA512_RSA_PKCS;
277*8617a60dSAndroid Build Coastguard Worker break;
278*8617a60dSAndroid Build Coastguard Worker default:
279*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Unsupported hash algorithm %d\n", hash_alg);
280*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
281*8617a60dSAndroid Build Coastguard Worker }
282*8617a60dSAndroid Build Coastguard Worker mechanism.pParameter = NULL;
283*8617a60dSAndroid Build Coastguard Worker mechanism.ulParameterLen = 0;
284*8617a60dSAndroid Build Coastguard Worker
285*8617a60dSAndroid Build Coastguard Worker CK_RV result = p11->C_SignInit(p11_key->session, &mechanism, p11_key->handle);
286*8617a60dSAndroid Build Coastguard Worker if (result != CKR_OK) {
287*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to sign init\n");
288*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
289*8617a60dSAndroid Build Coastguard Worker }
290*8617a60dSAndroid Build Coastguard Worker CK_ULONG ck_sig_size = sig_size;
291*8617a60dSAndroid Build Coastguard Worker result = p11->C_Sign(p11_key->session, (unsigned char *)data, data_size, sig,
292*8617a60dSAndroid Build Coastguard Worker &ck_sig_size);
293*8617a60dSAndroid Build Coastguard Worker if (result != CKR_OK) {
294*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to sign\n");
295*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
296*8617a60dSAndroid Build Coastguard Worker }
297*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
298*8617a60dSAndroid Build Coastguard Worker }
299*8617a60dSAndroid Build Coastguard Worker
pkcs11_free_key(struct pkcs11_key * p11_key)300*8617a60dSAndroid Build Coastguard Worker void pkcs11_free_key(struct pkcs11_key *p11_key)
301*8617a60dSAndroid Build Coastguard Worker {
302*8617a60dSAndroid Build Coastguard Worker if (!p11) {
303*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "pkcs11 is not loaded\n");
304*8617a60dSAndroid Build Coastguard Worker return;
305*8617a60dSAndroid Build Coastguard Worker }
306*8617a60dSAndroid Build Coastguard Worker CK_RV result = p11->C_CloseSession(p11_key->session);
307*8617a60dSAndroid Build Coastguard Worker if (result != CKR_OK)
308*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Failed to close session\n");
309*8617a60dSAndroid Build Coastguard Worker free(p11_key);
310*8617a60dSAndroid Build Coastguard Worker }
311