1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2017-2020, Linaro Limited
4 */
5
6 #include <ck_debug.h>
7 #include <inttypes.h>
8 #include <pkcs11.h>
9 #include <pkcs11_ta.h>
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include "ck_helpers.h"
14 #include "local_utils.h"
15 #include "serializer.h"
16 #include "serialize_ck.h"
17
18 /*
19 * Serialization and de-serialization logic
20 *
21 * Cryptoki API works in a way that user application uses memory references
22 * in object attributes description. TA can be invoked with only a small set
23 * of possible references to caller memory. Thus a Cryptoki object, made of
24 * data and pointers to data, is reassembled into a byte array where each
25 * attribute info (ID, value size, value) is appended with byte alignment. This
26 * so-called serialized object can be passed through the TA API.
27 *
28 * Initial entry to PKCS11 TA uses serialize_ck_attributes(). When TA
29 * returns with updated serialized data to be passed back to caller, we call
30 * deserialize_ck_attributes().
31 *
32 * Special handling is performed for CK_ULONG passing which may be either 32
33 * bits or 64 bits depending on target device architecture. In TA interface
34 * this is handled as unsigned 32 bit data type.
35 *
36 * When user application is querying attributes in example with
37 * C_GetAttributeValue() user may allocate larger value buffers. During entry
38 * to TA shared buffer is allocated in serialize_ck_attributes() based on
39 * caller's arguments. For each attribute TA verifies if value fits in
40 * the buffer and if it does, value is returned. Value size in buffer is
41 * updated to indicate real size of the value. When call is returned back to
42 * REE deserialize_ck_attributes() is invoked and then both input arguments and
43 * serialization buffer are used to return values to caller. Provided input
44 * arguments from caller are used to determine serialization buffer structure
45 * and then actual values and value sizes are then decoded from serialization
46 * buffer and returned to caller in caller's allocated memory.
47 */
48
49 /*
50 * Generic way of serializing CK keys, certificates, mechanism parameters, ...
51 * In cryptoki 2.40 parameters are almost all packaged as structure below:
52 */
53 struct ck_ref {
54 CK_ULONG id;
55 CK_BYTE_PTR ptr;
56 CK_ULONG len;
57 };
58
59 /*
60 * This is for attributes that contains data memory indirections.
61 * In other words, an attributes that defines a list of attributes.
62 * They are identified from the attribute type CKA_...
63 *
64 * @obj - ref used to track the serial object being created
65 * @attribute - pointer to a structure aligned of the CK_ATTRIBUTE struct
66 */
serialize_indirect_attribute(struct serializer * obj,CK_ATTRIBUTE_PTR attribute)67 static CK_RV serialize_indirect_attribute(struct serializer *obj,
68 CK_ATTRIBUTE_PTR attribute)
69 {
70 CK_ATTRIBUTE_PTR attr = NULL;
71 CK_ULONG count = 0;
72 CK_RV rv = CKR_GENERAL_ERROR;
73 struct serializer obj2 = { 0 };
74
75 switch (attribute->type) {
76 /* These are serialized each separately */
77 case CKA_DERIVE_TEMPLATE:
78 case CKA_WRAP_TEMPLATE:
79 case CKA_UNWRAP_TEMPLATE:
80 count = attribute->ulValueLen / sizeof(CK_ATTRIBUTE);
81 attr = (CK_ATTRIBUTE_PTR)attribute->pValue;
82 break;
83 default:
84 return CKR_NO_EVENT;
85 }
86
87 /* Create a serialized object for the content */
88 rv = serialize_ck_attributes(&obj2, attr, count);
89 if (rv)
90 return rv;
91
92 /*
93 * Append the created serialized object into target object:
94 * [attrib-id][byte-size][attributes-data]
95 */
96 rv = serialize_32b(obj, attribute->type);
97 if (rv)
98 goto out;
99
100 rv = serialize_32b(obj, obj2.size);
101 if (rv)
102 goto out;
103
104 rv = serialize_buffer(obj, obj2.buffer, obj2.size);
105 if (rv)
106 goto out;
107
108 obj->item_count++;
109 out:
110 release_serial_object(&obj2);
111
112 return rv;
113 }
114
deserialize_indirect_attribute(struct pkcs11_attribute_head * obj,CK_ATTRIBUTE_PTR attribute)115 static CK_RV deserialize_indirect_attribute(struct pkcs11_attribute_head *obj,
116 CK_ATTRIBUTE_PTR attribute)
117 {
118 CK_ULONG count = 0;
119 CK_ATTRIBUTE_PTR attr = NULL;
120
121 switch (attribute->type) {
122 /* These are serialized each separately */
123 case CKA_DERIVE_TEMPLATE:
124 case CKA_WRAP_TEMPLATE:
125 case CKA_UNWRAP_TEMPLATE:
126 count = attribute->ulValueLen / sizeof(CK_ATTRIBUTE);
127 attr = (CK_ATTRIBUTE_PTR)attribute->pValue;
128 break;
129 default:
130 return CKR_GENERAL_ERROR;
131 }
132
133 return deserialize_ck_attributes(obj->data, attr, count);
134 }
135
ck_attr_is_ulong(CK_ATTRIBUTE_TYPE attribute_id)136 static int ck_attr_is_ulong(CK_ATTRIBUTE_TYPE attribute_id)
137 {
138 switch (attribute_id) {
139 case CKA_CLASS:
140 case CKA_CERTIFICATE_TYPE:
141 case CKA_CERTIFICATE_CATEGORY:
142 case CKA_NAME_HASH_ALGORITHM:
143 case CKA_KEY_TYPE:
144 case CKA_HW_FEATURE_TYPE:
145 case CKA_MECHANISM_TYPE:
146 case CKA_KEY_GEN_MECHANISM:
147 case CKA_VALUE_LEN:
148 case CKA_MODULUS_BITS:
149 return true;
150 default:
151 return false;
152 }
153 }
154
serialize_ck_attribute(struct serializer * obj,CK_ATTRIBUTE * attr)155 static CK_RV serialize_ck_attribute(struct serializer *obj, CK_ATTRIBUTE *attr)
156 {
157 CK_MECHANISM_TYPE *type = NULL;
158 uint32_t pkcs11_size = 0;
159 uint32_t pkcs11_data32 = 0;
160 void *pkcs11_pdata = NULL;
161 uint32_t *mech_buf = NULL;
162 CK_RV rv = CKR_GENERAL_ERROR;
163 unsigned int n = 0;
164 unsigned int m = 0;
165
166 if (attr->type == PKCS11_UNDEFINED_ID)
167 return CKR_ATTRIBUTE_TYPE_INVALID;
168
169 switch (attr->type) {
170 case CKA_DERIVE_TEMPLATE:
171 case CKA_WRAP_TEMPLATE:
172 case CKA_UNWRAP_TEMPLATE:
173 return serialize_indirect_attribute(obj, attr);
174 case CKA_ALLOWED_MECHANISMS:
175 n = attr->ulValueLen / sizeof(CK_ULONG);
176 pkcs11_size = n * sizeof(uint32_t);
177 mech_buf = malloc(pkcs11_size);
178 if (!mech_buf)
179 return CKR_HOST_MEMORY;
180
181 type = attr->pValue;
182 for (m = 0; m < n; m++) {
183 mech_buf[m] = type[m];
184 if (mech_buf[m] == PKCS11_UNDEFINED_ID) {
185 rv = CKR_MECHANISM_INVALID;
186 goto out;
187 }
188 }
189 pkcs11_pdata = mech_buf;
190 break;
191 /* Attributes which data value do not need conversion (aside ulong) */
192 default:
193 pkcs11_pdata = attr->pValue;
194 if (!attr->pValue) {
195 pkcs11_size = 0;
196 } else if (ck_attr_is_ulong(attr->type)) {
197 CK_ULONG ck_ulong = 0;
198
199 if (attr->ulValueLen < sizeof(CK_ULONG))
200 return CKR_ATTRIBUTE_VALUE_INVALID;
201
202 memcpy(&ck_ulong, attr->pValue, sizeof(ck_ulong));
203 pkcs11_data32 = ck_ulong;
204 pkcs11_pdata = &pkcs11_data32;
205 pkcs11_size = sizeof(uint32_t);
206 } else {
207 pkcs11_size = attr->ulValueLen;
208 }
209 break;
210 }
211
212 rv = serialize_32b(obj, attr->type);
213 if (rv)
214 goto out;
215
216 rv = serialize_32b(obj, pkcs11_size);
217 if (rv)
218 goto out;
219
220 rv = serialize_buffer(obj, pkcs11_pdata, pkcs11_size);
221 if (rv)
222 goto out;
223
224 obj->item_count++;
225 out:
226 free(mech_buf);
227
228 return rv;
229 }
230
231 /* CK attribute reference arguments are list of attribute item */
serialize_ck_attributes(struct serializer * obj,CK_ATTRIBUTE_PTR attributes,CK_ULONG count)232 CK_RV serialize_ck_attributes(struct serializer *obj,
233 CK_ATTRIBUTE_PTR attributes, CK_ULONG count)
234 {
235 CK_ULONG n = 0;
236 CK_RV rv = CKR_OK;
237
238 rv = init_serial_object(obj);
239 if (rv)
240 return rv;
241
242 for (n = 0; n < count; n++) {
243 rv = serialize_ck_attribute(obj, attributes + n);
244 if (rv)
245 break;
246 }
247
248 if (rv)
249 release_serial_object(obj);
250 else
251 finalize_serial_object(obj);
252
253 return rv;
254 }
255
deserialize_mecha_list(CK_MECHANISM_TYPE * dst,void * src,size_t count)256 static CK_RV deserialize_mecha_list(CK_MECHANISM_TYPE *dst, void *src,
257 size_t count)
258 {
259 char *ta_src = src;
260 size_t n = 0;
261 uint32_t mecha_id = 0;
262
263 for (n = 0; n < count; n++) {
264 memcpy(&mecha_id, ta_src + n * sizeof(mecha_id),
265 sizeof(mecha_id));
266 dst[n] = mecha_id;
267 }
268
269 return CKR_OK;
270 }
271
deserialize_ck_attribute(struct pkcs11_attribute_head * in,uint8_t * data,CK_ATTRIBUTE_PTR out)272 static CK_RV deserialize_ck_attribute(struct pkcs11_attribute_head *in,
273 uint8_t *data, CK_ATTRIBUTE_PTR out)
274 {
275 CK_ULONG ck_ulong = 0;
276 uint32_t pkcs11_data32 = 0;
277 CK_RV rv = CKR_OK;
278
279 out->type = in->id;
280
281 if (in->size == PKCS11_CK_UNAVAILABLE_INFORMATION) {
282 out->ulValueLen = CK_UNAVAILABLE_INFORMATION;
283 return CKR_OK;
284 }
285
286 if (!out->pValue && ck_attr_is_ulong(out->type)) {
287 out->ulValueLen = sizeof(CK_ULONG);
288 return CKR_OK;
289 }
290
291 if (out->ulValueLen < in->size) {
292 out->ulValueLen = in->size;
293 return CKR_OK;
294 }
295
296 if (!out->pValue)
297 return CKR_OK;
298
299 /* Specific ulong encoded as 32bit in PKCS11 TA API */
300 if (ck_attr_is_ulong(out->type)) {
301 if (out->ulValueLen < sizeof(CK_ULONG))
302 return CKR_ATTRIBUTE_VALUE_INVALID;
303
304 memcpy(&pkcs11_data32, data, sizeof(uint32_t));
305 if (out->type == CKA_KEY_GEN_MECHANISM &&
306 pkcs11_data32 == PKCS11_CK_UNAVAILABLE_INFORMATION)
307 ck_ulong = CK_UNAVAILABLE_INFORMATION;
308 else
309 ck_ulong = pkcs11_data32;
310
311 memcpy(out->pValue, &ck_ulong, sizeof(CK_ULONG));
312 out->ulValueLen = sizeof(CK_ULONG);
313 return CKR_OK;
314 }
315
316 switch (out->type) {
317 case CKA_DERIVE_TEMPLATE:
318 case CKA_WRAP_TEMPLATE:
319 case CKA_UNWRAP_TEMPLATE:
320 rv = deserialize_indirect_attribute(in, out->pValue);
321 break;
322 case CKA_ALLOWED_MECHANISMS:
323 rv = deserialize_mecha_list(out->pValue, data,
324 in->size / sizeof(uint32_t));
325 out->ulValueLen = in->size / sizeof(uint32_t) *
326 sizeof(CK_ULONG);
327 break;
328 /* Attributes which data value do not need conversion (aside ulong) */
329 default:
330 memcpy(out->pValue, data, in->size);
331 out->ulValueLen = in->size;
332 break;
333 }
334
335 return rv;
336 }
337
deserialize_ck_attributes(uint8_t * in,CK_ATTRIBUTE_PTR attributes,CK_ULONG count)338 CK_RV deserialize_ck_attributes(uint8_t *in, CK_ATTRIBUTE_PTR attributes,
339 CK_ULONG count)
340 {
341 CK_ATTRIBUTE_PTR cur_attr = attributes;
342 CK_ULONG n = 0;
343 CK_RV rv = CKR_OK;
344 uint8_t *curr_head = in;
345 size_t len = 0;
346
347 curr_head += sizeof(struct pkcs11_object_head);
348
349 for (n = count; n > 0; n--, cur_attr++, curr_head += len) {
350 struct pkcs11_attribute_head *cli_ref = (void *)curr_head;
351 struct pkcs11_attribute_head cli_head = { 0 };
352 void *data_ptr = NULL;
353
354 /* Make copy if header so that is aligned properly. */
355 memcpy(&cli_head, cli_ref, sizeof(cli_head));
356
357 /* Get real data pointer from template data */
358 data_ptr = cli_ref->data;
359
360 len = sizeof(cli_head);
361
362 /* Advance by size provisioned in input serialized buffer */
363 if (cur_attr->pValue) {
364 if (ck_attr_is_ulong(cur_attr->type))
365 len += sizeof(uint32_t);
366 else
367 len += cur_attr->ulValueLen;
368 }
369
370 rv = deserialize_ck_attribute(&cli_head, data_ptr, cur_attr);
371 if (rv)
372 return rv;
373 }
374
375 return rv;
376 }
377
378 /*
379 * Serialization of CK mechanism parameters
380 *
381 * Most mechanism have no parameters.
382 * Some mechanism have a single 32bit parameter.
383 * Some mechanism have a specific parameter structure which may contain
384 * indirected data (data referred by a buffer pointer).
385 *
386 * Below are each structure specific mechanisms parameters.
387 */
388
serialize_mecha_aes_ctr(struct serializer * obj,CK_MECHANISM_PTR mecha)389 static CK_RV serialize_mecha_aes_ctr(struct serializer *obj,
390 CK_MECHANISM_PTR mecha)
391 {
392 CK_AES_CTR_PARAMS_PTR param = mecha->pParameter;
393 CK_RV rv = CKR_GENERAL_ERROR;
394 uint32_t size = 0;
395
396 rv = serialize_32b(obj, obj->type);
397 if (rv)
398 return rv;
399
400 size = sizeof(uint32_t) + sizeof(param->cb);
401 rv = serialize_32b(obj, size);
402 if (rv)
403 return rv;
404
405 rv = serialize_ck_ulong(obj, param->ulCounterBits);
406 if (rv)
407 return rv;
408
409 rv = serialize_buffer(obj, param->cb, sizeof(param->cb));
410 if (rv)
411 return rv;
412
413 return rv;
414 }
415
serialize_mecha_aes_gcm(struct serializer * obj,CK_MECHANISM_PTR mecha)416 static CK_RV serialize_mecha_aes_gcm(struct serializer *obj,
417 CK_MECHANISM_PTR mecha)
418 {
419 CK_GCM_PARAMS_PTR param = mecha->pParameter;
420 CK_RV rv = CKR_GENERAL_ERROR;
421 CK_ULONG aad_len = 0;
422
423 /* AAD is not manadatory */
424 if (param->pAAD)
425 aad_len = param->ulAADLen;
426
427 if (!param->pIv)
428 return CKR_MECHANISM_PARAM_INVALID;
429
430 rv = serialize_32b(obj, obj->type);
431 if (rv)
432 return rv;
433
434 rv = serialize_32b(obj, 3 * sizeof(uint32_t) +
435 param->ulIvLen + aad_len);
436 if (rv)
437 return rv;
438
439 rv = serialize_ck_ulong(obj, param->ulIvLen);
440 if (rv)
441 return rv;
442
443 rv = serialize_buffer(obj, param->pIv, param->ulIvLen);
444 if (rv)
445 return rv;
446
447 rv = serialize_ck_ulong(obj, aad_len);
448 if (rv)
449 return rv;
450
451 rv = serialize_buffer(obj, param->pAAD, aad_len);
452 if (rv)
453 return rv;
454
455 return serialize_ck_ulong(obj, param->ulTagBits);
456 }
457
serialize_mecha_aes_iv(struct serializer * obj,CK_MECHANISM_PTR mecha)458 static CK_RV serialize_mecha_aes_iv(struct serializer *obj,
459 CK_MECHANISM_PTR mecha)
460 {
461 uint32_t iv_size = mecha->ulParameterLen;
462 CK_RV rv = CKR_GENERAL_ERROR;
463
464 rv = serialize_32b(obj, obj->type);
465 if (rv)
466 return rv;
467
468 rv = serialize_32b(obj, iv_size);
469 if (rv)
470 return rv;
471
472 return serialize_buffer(obj, mecha->pParameter, mecha->ulParameterLen);
473 }
474
serialize_mecha_key_deriv_str(struct serializer * obj,CK_MECHANISM_PTR mecha)475 static CK_RV serialize_mecha_key_deriv_str(struct serializer *obj,
476 CK_MECHANISM_PTR mecha)
477 {
478 CK_KEY_DERIVATION_STRING_DATA_PTR param = mecha->pParameter;
479 CK_RV rv = CKR_GENERAL_ERROR;
480 uint32_t size = 0;
481
482 rv = serialize_32b(obj, obj->type);
483 if (rv)
484 return rv;
485
486 size = sizeof(uint32_t) + param->ulLen;
487 rv = serialize_32b(obj, size);
488 if (rv)
489 return rv;
490
491 rv = serialize_ck_ulong(obj, param->ulLen);
492 if (rv)
493 return rv;
494
495 return serialize_buffer(obj, param->pData, param->ulLen);
496 }
497
serialize_mecha_ecdh1_derive_param(struct serializer * obj,CK_MECHANISM_PTR mecha)498 static CK_RV serialize_mecha_ecdh1_derive_param(struct serializer *obj,
499 CK_MECHANISM_PTR mecha)
500 {
501 CK_ECDH1_DERIVE_PARAMS *params = mecha->pParameter;
502 CK_RV rv = CKR_GENERAL_ERROR;
503 size_t params_size = 3 * sizeof(uint32_t) + params->ulSharedDataLen +
504 params->ulPublicDataLen;
505
506 rv = serialize_32b(obj, obj->type);
507 if (rv)
508 return rv;
509
510 rv = serialize_32b(obj, params_size);
511 if (rv)
512 return rv;
513
514 rv = serialize_32b(obj, params->kdf);
515 if (rv)
516 return rv;
517
518 rv = serialize_32b(obj, params->ulSharedDataLen);
519 if (rv)
520 return rv;
521
522 rv = serialize_buffer(obj, params->pSharedData,
523 params->ulSharedDataLen);
524 if (rv)
525 return rv;
526
527 rv = serialize_32b(obj, params->ulPublicDataLen);
528 if (rv)
529 return rv;
530
531 return serialize_buffer(obj, params->pPublicData,
532 params->ulPublicDataLen);
533 }
534
serialize_mecha_aes_cbc_encrypt_data(struct serializer * obj,CK_MECHANISM_PTR mecha)535 static CK_RV serialize_mecha_aes_cbc_encrypt_data(struct serializer *obj,
536 CK_MECHANISM_PTR mecha)
537 {
538 CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR param = mecha->pParameter;
539 CK_RV rv = CKR_GENERAL_ERROR;
540 uint32_t size = 0;
541
542 rv = serialize_32b(obj, obj->type);
543 if (rv)
544 return rv;
545
546 size = sizeof(param->iv) + sizeof(uint32_t) + param->length;
547 rv = serialize_32b(obj, size);
548 if (rv)
549 return rv;
550
551 rv = serialize_buffer(obj, param->iv, sizeof(param->iv));
552 if (rv)
553 return rv;
554
555 rv = serialize_ck_ulong(obj, param->length);
556 if (rv)
557 return rv;
558
559 return serialize_buffer(obj, param->pData, param->length);
560 }
561
serialize_mecha_rsa_pss_param(struct serializer * obj,CK_MECHANISM_PTR mecha)562 static CK_RV serialize_mecha_rsa_pss_param(struct serializer *obj,
563 CK_MECHANISM_PTR mecha)
564 {
565 CK_RSA_PKCS_PSS_PARAMS *params = mecha->pParameter;
566 CK_RV rv = CKR_GENERAL_ERROR;
567 uint32_t params_size = 3 * sizeof(uint32_t);
568
569 if (mecha->ulParameterLen != sizeof(*params))
570 return CKR_ARGUMENTS_BAD;
571
572 rv = serialize_32b(obj, obj->type);
573 if (rv)
574 return rv;
575
576 rv = serialize_32b(obj, params_size);
577 if (rv)
578 return rv;
579
580 rv = serialize_ck_ulong(obj, params->hashAlg);
581 if (rv)
582 return rv;
583
584 rv = serialize_ck_ulong(obj, params->mgf);
585 if (rv)
586 return rv;
587
588 return serialize_ck_ulong(obj, params->sLen);
589 }
590
serialize_mecha_rsa_oaep_param(struct serializer * obj,CK_MECHANISM_PTR mecha)591 static CK_RV serialize_mecha_rsa_oaep_param(struct serializer *obj,
592 CK_MECHANISM_PTR mecha)
593 {
594 CK_RSA_PKCS_OAEP_PARAMS *params = mecha->pParameter;
595 CK_RV rv = CKR_GENERAL_ERROR;
596 size_t params_size = 4 * sizeof(uint32_t) + params->ulSourceDataLen;
597
598 if (mecha->ulParameterLen != sizeof(*params))
599 return CKR_ARGUMENTS_BAD;
600
601 rv = serialize_32b(obj, obj->type);
602 if (rv)
603 return rv;
604
605 rv = serialize_32b(obj, params_size);
606 if (rv)
607 return rv;
608
609 rv = serialize_ck_ulong(obj, params->hashAlg);
610 if (rv)
611 return rv;
612
613 rv = serialize_ck_ulong(obj, params->mgf);
614 if (rv)
615 return rv;
616
617 rv = serialize_ck_ulong(obj, params->source);
618 if (rv)
619 return rv;
620
621 rv = serialize_ck_ulong(obj, params->ulSourceDataLen);
622 if (rv)
623 return rv;
624
625 return serialize_buffer(obj, params->pSourceData,
626 params->ulSourceDataLen);
627 }
628
serialize_mecha_rsa_aes_key_wrap(struct serializer * obj,CK_MECHANISM_PTR mecha)629 static CK_RV serialize_mecha_rsa_aes_key_wrap(struct serializer *obj,
630 CK_MECHANISM_PTR mecha)
631 {
632 CK_RSA_AES_KEY_WRAP_PARAMS *params = mecha->pParameter;
633 CK_RSA_PKCS_OAEP_PARAMS *aes_params = params->pOAEPParams;
634 CK_RV rv = CKR_GENERAL_ERROR;
635 size_t params_size = 5 * sizeof(uint32_t) + aes_params->ulSourceDataLen;
636
637 if (mecha->ulParameterLen != sizeof(*params))
638 return CKR_ARGUMENTS_BAD;
639
640 rv = serialize_32b(obj, obj->type);
641 if (rv)
642 return rv;
643
644 rv = serialize_32b(obj, params_size);
645 if (rv)
646 return rv;
647
648 rv = serialize_ck_ulong(obj, params->ulAESKeyBits);
649 if (rv)
650 return rv;
651
652 rv = serialize_ck_ulong(obj, aes_params->hashAlg);
653 if (rv)
654 return rv;
655
656 rv = serialize_ck_ulong(obj, aes_params->mgf);
657 if (rv)
658 return rv;
659
660 rv = serialize_ck_ulong(obj, aes_params->source);
661 if (rv)
662 return rv;
663
664 rv = serialize_ck_ulong(obj, aes_params->ulSourceDataLen);
665 if (rv)
666 return rv;
667
668 return serialize_buffer(obj, aes_params->pSourceData,
669 aes_params->ulSourceDataLen);
670 }
671
serialize_mecha_eddsa(struct serializer * obj,CK_MECHANISM_PTR mecha)672 static CK_RV serialize_mecha_eddsa(struct serializer *obj,
673 CK_MECHANISM_PTR mecha)
674 {
675 CK_RV rv = CKR_GENERAL_ERROR;
676 CK_EDDSA_PARAMS *params = mecha->pParameter;
677 CK_ULONG params_len = mecha->ulParameterLen;
678 /*
679 * When no parameter is provided, the expected operation is
680 * no-prehash and no-context.
681 */
682 CK_EDDSA_PARAMS default_params = {
683 .phFlag = 0,
684 .ulContextDataLen = 0,
685 };
686
687 if (params_len == 0) {
688 params = &default_params;
689 params_len = sizeof(*params);
690 }
691
692 if (params_len != sizeof(*params))
693 return CKR_ARGUMENTS_BAD;
694
695 rv = serialize_32b(obj, obj->type);
696 if (rv)
697 return rv;
698
699 rv = serialize_32b(obj, 2 * sizeof(uint32_t) + params->ulContextDataLen);
700 if (rv)
701 return rv;
702
703 rv = serialize_32b(obj, params->phFlag);
704 if (rv)
705 return rv;
706
707 rv = serialize_32b(obj, params->ulContextDataLen);
708 if (rv)
709 return rv;
710
711 return serialize_buffer(obj, params->pContextData, params->ulContextDataLen);
712 }
713
serialize_mecha_mac_general_param(struct serializer * obj,CK_MECHANISM_PTR mecha)714 static CK_RV serialize_mecha_mac_general_param(struct serializer *obj,
715 CK_MECHANISM_PTR mecha)
716 {
717 CK_RV rv = CKR_GENERAL_ERROR;
718 CK_ULONG ck_data = 0;
719
720 if (mecha->ulParameterLen != sizeof(ck_data))
721 return CKR_ARGUMENTS_BAD;
722
723 memcpy(&ck_data, mecha->pParameter, mecha->ulParameterLen);
724
725 rv = serialize_32b(obj, obj->type);
726 if (rv)
727 return rv;
728
729 rv = serialize_32b(obj, sizeof(uint32_t));
730 if (rv)
731 return rv;
732
733 return serialize_ck_ulong(obj, ck_data);
734 }
735
736 /**
737 * serialize_ck_mecha_params - serialize a mechanism type & params
738 *
739 * @obj - serializer used to track the serialization
740 * @mechanism - pointer of the in structure aligned CK_MECHANISM.
741 *
742 * Serialized content:
743 * [mechanism-type][mechanism-param-blob]
744 *
745 * [mechanism-param-blob] depends on mechanism type ID, see
746 * serialize_mecha_XXX().
747 */
serialize_ck_mecha_params(struct serializer * obj,CK_MECHANISM_PTR mechanism)748 CK_RV serialize_ck_mecha_params(struct serializer *obj,
749 CK_MECHANISM_PTR mechanism)
750 {
751 CK_MECHANISM mecha = { 0 };
752 CK_RV rv = CKR_GENERAL_ERROR;
753
754 memset(obj, 0, sizeof(*obj));
755
756 obj->object = PKCS11_CKO_MECHANISM;
757
758 mecha = *mechanism;
759 obj->type = mecha.mechanism;
760 if (obj->type == PKCS11_UNDEFINED_ID)
761 return CKR_MECHANISM_INVALID;
762
763 switch (mecha.mechanism) {
764 case CKM_GENERIC_SECRET_KEY_GEN:
765 case CKM_AES_KEY_GEN:
766 case CKM_AES_ECB:
767 case CKM_AES_CMAC:
768 case CKM_MD5:
769 case CKM_SHA_1:
770 case CKM_SHA224:
771 case CKM_SHA256:
772 case CKM_SHA384:
773 case CKM_SHA512:
774 case CKM_MD5_HMAC:
775 case CKM_SHA_1_HMAC:
776 case CKM_SHA224_HMAC:
777 case CKM_SHA256_HMAC:
778 case CKM_SHA384_HMAC:
779 case CKM_SHA512_HMAC:
780 case CKM_EC_KEY_PAIR_GEN:
781 case CKM_EC_EDWARDS_KEY_PAIR_GEN:
782 case CKM_ECDSA:
783 case CKM_ECDSA_SHA1:
784 case CKM_ECDSA_SHA224:
785 case CKM_ECDSA_SHA256:
786 case CKM_ECDSA_SHA384:
787 case CKM_ECDSA_SHA512:
788 case CKM_RSA_PKCS_KEY_PAIR_GEN:
789 case CKM_RSA_PKCS:
790 case CKM_RSA_X_509:
791 case CKM_MD5_RSA_PKCS:
792 case CKM_SHA1_RSA_PKCS:
793 case CKM_SHA224_RSA_PKCS:
794 case CKM_SHA256_RSA_PKCS:
795 case CKM_SHA384_RSA_PKCS:
796 case CKM_SHA512_RSA_PKCS:
797 /* No parameter expected, size shall be 0 */
798 if (mechanism->ulParameterLen)
799 return CKR_MECHANISM_PARAM_INVALID;
800
801 rv = serialize_32b(obj, obj->type);
802 if (rv)
803 return rv;
804
805 return serialize_32b(obj, 0);
806
807 case CKM_EDDSA:
808 return serialize_mecha_eddsa(obj, &mecha);
809
810 case CKM_AES_CBC:
811 case CKM_AES_CBC_PAD:
812 case CKM_AES_CTS:
813 return serialize_mecha_aes_iv(obj, &mecha);
814
815 case CKM_AES_CTR:
816 return serialize_mecha_aes_ctr(obj, &mecha);
817
818 case CKM_AES_GCM:
819 return serialize_mecha_aes_gcm(obj, &mecha);
820
821 case CKM_AES_ECB_ENCRYPT_DATA:
822 return serialize_mecha_key_deriv_str(obj, &mecha);
823
824 case CKM_AES_CBC_ENCRYPT_DATA:
825 return serialize_mecha_aes_cbc_encrypt_data(obj, &mecha);
826
827 case CKM_ECDH1_DERIVE:
828 case CKM_ECDH1_COFACTOR_DERIVE:
829 return serialize_mecha_ecdh1_derive_param(obj, &mecha);
830
831 case CKM_RSA_PKCS_PSS:
832 case CKM_SHA1_RSA_PKCS_PSS:
833 case CKM_SHA256_RSA_PKCS_PSS:
834 case CKM_SHA384_RSA_PKCS_PSS:
835 case CKM_SHA512_RSA_PKCS_PSS:
836 case CKM_SHA224_RSA_PKCS_PSS:
837 return serialize_mecha_rsa_pss_param(obj, &mecha);
838
839 case CKM_RSA_PKCS_OAEP:
840 return serialize_mecha_rsa_oaep_param(obj, &mecha);
841
842 case CKM_AES_CMAC_GENERAL:
843 case CKM_MD5_HMAC_GENERAL:
844 case CKM_SHA_1_HMAC_GENERAL:
845 case CKM_SHA224_HMAC_GENERAL:
846 case CKM_SHA256_HMAC_GENERAL:
847 case CKM_SHA384_HMAC_GENERAL:
848 case CKM_SHA512_HMAC_GENERAL:
849 return serialize_mecha_mac_general_param(obj, &mecha);
850 case CKM_RSA_AES_KEY_WRAP:
851 return serialize_mecha_rsa_aes_key_wrap(obj, &mecha);
852
853 default:
854 return CKR_MECHANISM_INVALID;
855 }
856 }
857