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 return rv;
99
100 rv = serialize_32b(obj, obj2.size);
101 if (rv)
102 return rv;
103
104 rv = serialize_buffer(obj, obj2.buffer, obj2.size);
105 if (rv)
106 return rv;
107
108 obj->item_count++;
109
110 return rv;
111 }
112
deserialize_indirect_attribute(struct pkcs11_attribute_head * obj,CK_ATTRIBUTE_PTR attribute)113 static CK_RV deserialize_indirect_attribute(struct pkcs11_attribute_head *obj,
114 CK_ATTRIBUTE_PTR attribute)
115 {
116 CK_ULONG count = 0;
117 CK_ATTRIBUTE_PTR attr = NULL;
118
119 switch (attribute->type) {
120 /* These are serialized each separately */
121 case CKA_DERIVE_TEMPLATE:
122 case CKA_WRAP_TEMPLATE:
123 case CKA_UNWRAP_TEMPLATE:
124 count = attribute->ulValueLen / sizeof(CK_ATTRIBUTE);
125 attr = (CK_ATTRIBUTE_PTR)attribute->pValue;
126 break;
127 default:
128 return CKR_GENERAL_ERROR;
129 }
130
131 return deserialize_ck_attributes(obj->data, attr, count);
132 }
133
ck_attr_is_ulong(CK_ATTRIBUTE_TYPE attribute_id)134 static int ck_attr_is_ulong(CK_ATTRIBUTE_TYPE attribute_id)
135 {
136 switch (attribute_id) {
137 case CKA_CLASS:
138 case CKA_CERTIFICATE_TYPE:
139 case CKA_CERTIFICATE_CATEGORY:
140 case CKA_NAME_HASH_ALGORITHM:
141 case CKA_KEY_TYPE:
142 case CKA_HW_FEATURE_TYPE:
143 case CKA_MECHANISM_TYPE:
144 case CKA_KEY_GEN_MECHANISM:
145 case CKA_VALUE_LEN:
146 case CKA_MODULUS_BITS:
147 return true;
148 default:
149 return false;
150 }
151 }
152
serialize_ck_attribute(struct serializer * obj,CK_ATTRIBUTE * attr)153 static CK_RV serialize_ck_attribute(struct serializer *obj, CK_ATTRIBUTE *attr)
154 {
155 CK_MECHANISM_TYPE *type = NULL;
156 uint32_t pkcs11_size = 0;
157 uint32_t pkcs11_data32 = 0;
158 void *pkcs11_pdata = NULL;
159 uint32_t *mech_buf = NULL;
160 CK_RV rv = CKR_GENERAL_ERROR;
161 unsigned int n = 0;
162 unsigned int m = 0;
163
164 if (attr->type == PKCS11_UNDEFINED_ID)
165 return CKR_ATTRIBUTE_TYPE_INVALID;
166
167 switch (attr->type) {
168 case CKA_DERIVE_TEMPLATE:
169 case CKA_WRAP_TEMPLATE:
170 case CKA_UNWRAP_TEMPLATE:
171 return serialize_indirect_attribute(obj, attr);
172 case CKA_ALLOWED_MECHANISMS:
173 n = attr->ulValueLen / sizeof(CK_ULONG);
174 pkcs11_size = n * sizeof(uint32_t);
175 mech_buf = malloc(pkcs11_size);
176 if (!mech_buf)
177 return CKR_HOST_MEMORY;
178
179 type = attr->pValue;
180 for (m = 0; m < n; m++) {
181 mech_buf[m] = type[m];
182 if (mech_buf[m] == PKCS11_UNDEFINED_ID) {
183 rv = CKR_MECHANISM_INVALID;
184 goto out;
185 }
186 }
187 pkcs11_pdata = mech_buf;
188 break;
189 /* Attributes which data value do not need conversion (aside ulong) */
190 default:
191 pkcs11_pdata = attr->pValue;
192 if (!attr->pValue) {
193 pkcs11_size = 0;
194 } else if (ck_attr_is_ulong(attr->type)) {
195 CK_ULONG ck_ulong = 0;
196
197 if (attr->ulValueLen < sizeof(CK_ULONG))
198 return CKR_ATTRIBUTE_VALUE_INVALID;
199
200 memcpy(&ck_ulong, attr->pValue, sizeof(ck_ulong));
201 pkcs11_data32 = ck_ulong;
202 pkcs11_pdata = &pkcs11_data32;
203 pkcs11_size = sizeof(uint32_t);
204 } else {
205 pkcs11_size = attr->ulValueLen;
206 }
207 break;
208 }
209
210 rv = serialize_32b(obj, attr->type);
211 if (rv)
212 goto out;
213
214 rv = serialize_32b(obj, pkcs11_size);
215 if (rv)
216 goto out;
217
218 rv = serialize_buffer(obj, pkcs11_pdata, pkcs11_size);
219 if (rv)
220 goto out;
221
222 obj->item_count++;
223 out:
224 free(mech_buf);
225
226 return rv;
227 }
228
229 /* CK attribute reference arguments are list of attribute item */
serialize_ck_attributes(struct serializer * obj,CK_ATTRIBUTE_PTR attributes,CK_ULONG count)230 CK_RV serialize_ck_attributes(struct serializer *obj,
231 CK_ATTRIBUTE_PTR attributes, CK_ULONG count)
232 {
233 CK_ULONG n = 0;
234 CK_RV rv = CKR_OK;
235
236 rv = init_serial_object(obj);
237 if (rv)
238 return rv;
239
240 for (n = 0; n < count; n++) {
241 rv = serialize_ck_attribute(obj, attributes + n);
242 if (rv)
243 break;
244 }
245
246 if (rv)
247 release_serial_object(obj);
248 else
249 finalize_serial_object(obj);
250
251 return rv;
252 }
253
deserialize_mecha_list(CK_MECHANISM_TYPE * dst,void * src,size_t count)254 static CK_RV deserialize_mecha_list(CK_MECHANISM_TYPE *dst, void *src,
255 size_t count)
256 {
257 char *ta_src = src;
258 size_t n = 0;
259 uint32_t mecha_id = 0;
260
261 for (n = 0; n < count; n++) {
262 memcpy(&mecha_id, ta_src + n * sizeof(mecha_id),
263 sizeof(mecha_id));
264 dst[n] = mecha_id;
265 }
266
267 return CKR_OK;
268 }
269
deserialize_ck_attribute(struct pkcs11_attribute_head * in,uint8_t * data,CK_ATTRIBUTE_PTR out)270 static CK_RV deserialize_ck_attribute(struct pkcs11_attribute_head *in,
271 uint8_t *data, CK_ATTRIBUTE_PTR out)
272 {
273 CK_ULONG ck_ulong = 0;
274 uint32_t pkcs11_data32 = 0;
275 CK_RV rv = CKR_OK;
276
277 out->type = in->id;
278
279 if (in->size == PKCS11_CK_UNAVAILABLE_INFORMATION) {
280 out->ulValueLen = CK_UNAVAILABLE_INFORMATION;
281 return CKR_OK;
282 }
283
284 if (!out->pValue && ck_attr_is_ulong(out->type)) {
285 out->ulValueLen = sizeof(CK_ULONG);
286 return CKR_OK;
287 }
288
289 if (out->ulValueLen < in->size) {
290 out->ulValueLen = in->size;
291 return CKR_OK;
292 }
293
294 if (!out->pValue)
295 return CKR_OK;
296
297 /* Specific ulong encoded as 32bit in PKCS11 TA API */
298 if (ck_attr_is_ulong(out->type)) {
299 if (out->ulValueLen < sizeof(CK_ULONG))
300 return CKR_ATTRIBUTE_VALUE_INVALID;
301
302 memcpy(&pkcs11_data32, data, sizeof(uint32_t));
303 if (out->type == CKA_KEY_GEN_MECHANISM &&
304 pkcs11_data32 == PKCS11_CK_UNAVAILABLE_INFORMATION)
305 ck_ulong = CK_UNAVAILABLE_INFORMATION;
306 else
307 ck_ulong = pkcs11_data32;
308
309 memcpy(out->pValue, &ck_ulong, sizeof(CK_ULONG));
310 out->ulValueLen = sizeof(CK_ULONG);
311 return CKR_OK;
312 }
313
314 switch (out->type) {
315 case CKA_DERIVE_TEMPLATE:
316 case CKA_WRAP_TEMPLATE:
317 case CKA_UNWRAP_TEMPLATE:
318 rv = deserialize_indirect_attribute(in, out->pValue);
319 break;
320 case CKA_ALLOWED_MECHANISMS:
321 rv = deserialize_mecha_list(out->pValue, data,
322 in->size / sizeof(uint32_t));
323 out->ulValueLen = in->size / sizeof(uint32_t) *
324 sizeof(CK_ULONG);
325 break;
326 /* Attributes which data value do not need conversion (aside ulong) */
327 default:
328 memcpy(out->pValue, data, in->size);
329 out->ulValueLen = in->size;
330 break;
331 }
332
333 return rv;
334 }
335
deserialize_ck_attributes(uint8_t * in,CK_ATTRIBUTE_PTR attributes,CK_ULONG count)336 CK_RV deserialize_ck_attributes(uint8_t *in, CK_ATTRIBUTE_PTR attributes,
337 CK_ULONG count)
338 {
339 CK_ATTRIBUTE_PTR cur_attr = attributes;
340 CK_ULONG n = 0;
341 CK_RV rv = CKR_OK;
342 uint8_t *curr_head = in;
343 size_t len = 0;
344
345 curr_head += sizeof(struct pkcs11_object_head);
346
347 for (n = count; n > 0; n--, cur_attr++, curr_head += len) {
348 struct pkcs11_attribute_head *cli_ref = (void *)curr_head;
349 struct pkcs11_attribute_head cli_head = { 0 };
350 void *data_ptr = NULL;
351
352 /* Make copy if header so that is aligned properly. */
353 memcpy(&cli_head, cli_ref, sizeof(cli_head));
354
355 /* Get real data pointer from template data */
356 data_ptr = cli_ref->data;
357
358 len = sizeof(cli_head);
359
360 /* Advance by size provisioned in input serialized buffer */
361 if (cur_attr->pValue) {
362 if (ck_attr_is_ulong(cur_attr->type))
363 len += sizeof(uint32_t);
364 else
365 len += cur_attr->ulValueLen;
366 }
367
368 rv = deserialize_ck_attribute(&cli_head, data_ptr, cur_attr);
369 if (rv)
370 return rv;
371 }
372
373 return rv;
374 }
375
376 /*
377 * Serialization of CK mechanism parameters
378 *
379 * Most mechanism have no parameters.
380 * Some mechanism have a single 32bit parameter.
381 * Some mechanism have a specific parameter structure which may contain
382 * indirected data (data referred by a buffer pointer).
383 *
384 * Below are each structure specific mechanisms parameters.
385 */
386
serialize_mecha_aes_ctr(struct serializer * obj,CK_MECHANISM_PTR mecha)387 static CK_RV serialize_mecha_aes_ctr(struct serializer *obj,
388 CK_MECHANISM_PTR mecha)
389 {
390 CK_AES_CTR_PARAMS_PTR param = mecha->pParameter;
391 CK_RV rv = CKR_GENERAL_ERROR;
392 uint32_t size = 0;
393
394 rv = serialize_32b(obj, obj->type);
395 if (rv)
396 return rv;
397
398 size = sizeof(uint32_t) + sizeof(param->cb);
399 rv = serialize_32b(obj, size);
400 if (rv)
401 return rv;
402
403 rv = serialize_ck_ulong(obj, param->ulCounterBits);
404 if (rv)
405 return rv;
406
407 rv = serialize_buffer(obj, param->cb, sizeof(param->cb));
408 if (rv)
409 return rv;
410
411 return rv;
412 }
413
serialize_mecha_aes_iv(struct serializer * obj,CK_MECHANISM_PTR mecha)414 static CK_RV serialize_mecha_aes_iv(struct serializer *obj,
415 CK_MECHANISM_PTR mecha)
416 {
417 uint32_t iv_size = mecha->ulParameterLen;
418 CK_RV rv = CKR_GENERAL_ERROR;
419
420 rv = serialize_32b(obj, obj->type);
421 if (rv)
422 return rv;
423
424 rv = serialize_32b(obj, iv_size);
425 if (rv)
426 return rv;
427
428 return serialize_buffer(obj, mecha->pParameter, mecha->ulParameterLen);
429 }
430
serialize_mecha_key_deriv_str(struct serializer * obj,CK_MECHANISM_PTR mecha)431 static CK_RV serialize_mecha_key_deriv_str(struct serializer *obj,
432 CK_MECHANISM_PTR mecha)
433 {
434 CK_KEY_DERIVATION_STRING_DATA_PTR param = mecha->pParameter;
435 CK_RV rv = CKR_GENERAL_ERROR;
436 uint32_t size = 0;
437
438 rv = serialize_32b(obj, obj->type);
439 if (rv)
440 return rv;
441
442 size = sizeof(uint32_t) + param->ulLen;
443 rv = serialize_32b(obj, size);
444 if (rv)
445 return rv;
446
447 rv = serialize_ck_ulong(obj, param->ulLen);
448 if (rv)
449 return rv;
450
451 return serialize_buffer(obj, param->pData, param->ulLen);
452 }
453
serialize_mecha_aes_cbc_encrypt_data(struct serializer * obj,CK_MECHANISM_PTR mecha)454 static CK_RV serialize_mecha_aes_cbc_encrypt_data(struct serializer *obj,
455 CK_MECHANISM_PTR mecha)
456 {
457 CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR param = mecha->pParameter;
458 CK_RV rv = CKR_GENERAL_ERROR;
459 uint32_t size = 0;
460
461 rv = serialize_32b(obj, obj->type);
462 if (rv)
463 return rv;
464
465 size = sizeof(param->iv) + sizeof(uint32_t) + param->length;
466 rv = serialize_32b(obj, size);
467 if (rv)
468 return rv;
469
470 rv = serialize_buffer(obj, param->iv, sizeof(param->iv));
471 if (rv)
472 return rv;
473
474 rv = serialize_ck_ulong(obj, param->length);
475 if (rv)
476 return rv;
477
478 return serialize_buffer(obj, param->pData, param->length);
479 }
480
serialize_mecha_rsa_pss_param(struct serializer * obj,CK_MECHANISM_PTR mecha)481 static CK_RV serialize_mecha_rsa_pss_param(struct serializer *obj,
482 CK_MECHANISM_PTR mecha)
483 {
484 CK_RSA_PKCS_PSS_PARAMS *params = mecha->pParameter;
485 CK_RV rv = CKR_GENERAL_ERROR;
486 uint32_t params_size = 3 * sizeof(uint32_t);
487
488 if (mecha->ulParameterLen != sizeof(*params))
489 return CKR_ARGUMENTS_BAD;
490
491 rv = serialize_32b(obj, obj->type);
492 if (rv)
493 return rv;
494
495 rv = serialize_32b(obj, params_size);
496 if (rv)
497 return rv;
498
499 rv = serialize_ck_ulong(obj, params->hashAlg);
500 if (rv)
501 return rv;
502
503 rv = serialize_ck_ulong(obj, params->mgf);
504 if (rv)
505 return rv;
506
507 return serialize_ck_ulong(obj, params->sLen);
508 }
509
serialize_mecha_rsa_oaep_param(struct serializer * obj,CK_MECHANISM_PTR mecha)510 static CK_RV serialize_mecha_rsa_oaep_param(struct serializer *obj,
511 CK_MECHANISM_PTR mecha)
512 {
513 CK_RSA_PKCS_OAEP_PARAMS *params = mecha->pParameter;
514 CK_RV rv = CKR_GENERAL_ERROR;
515 size_t params_size = 4 * sizeof(uint32_t) + params->ulSourceDataLen;
516
517 if (mecha->ulParameterLen != sizeof(*params))
518 return CKR_ARGUMENTS_BAD;
519
520 rv = serialize_32b(obj, obj->type);
521 if (rv)
522 return rv;
523
524 rv = serialize_32b(obj, params_size);
525 if (rv)
526 return rv;
527
528 rv = serialize_ck_ulong(obj, params->hashAlg);
529 if (rv)
530 return rv;
531
532 rv = serialize_ck_ulong(obj, params->mgf);
533 if (rv)
534 return rv;
535
536 rv = serialize_ck_ulong(obj, params->source);
537 if (rv)
538 return rv;
539
540 rv = serialize_ck_ulong(obj, params->ulSourceDataLen);
541 if (rv)
542 return rv;
543
544 return serialize_buffer(obj, params->pSourceData,
545 params->ulSourceDataLen);
546 }
547
serialize_mecha_mac_general_param(struct serializer * obj,CK_MECHANISM_PTR mecha)548 static CK_RV serialize_mecha_mac_general_param(struct serializer *obj,
549 CK_MECHANISM_PTR mecha)
550 {
551 CK_RV rv = CKR_GENERAL_ERROR;
552 CK_ULONG ck_data = 0;
553
554 if (mecha->ulParameterLen != sizeof(ck_data))
555 return CKR_ARGUMENTS_BAD;
556
557 memcpy(&ck_data, mecha->pParameter, mecha->ulParameterLen);
558
559 rv = serialize_32b(obj, obj->type);
560 if (rv)
561 return rv;
562
563 rv = serialize_32b(obj, sizeof(uint32_t));
564 if (rv)
565 return rv;
566
567 return serialize_ck_ulong(obj, ck_data);
568 }
569
570 /**
571 * serialize_ck_mecha_params - serialize a mechanism type & params
572 *
573 * @obj - serializer used to track the serialization
574 * @mechanism - pointer of the in structure aligned CK_MECHANISM.
575 *
576 * Serialized content:
577 * [mechanism-type][mechanism-param-blob]
578 *
579 * [mechanism-param-blob] depends on mechanism type ID, see
580 * serialize_mecha_XXX().
581 */
serialize_ck_mecha_params(struct serializer * obj,CK_MECHANISM_PTR mechanism)582 CK_RV serialize_ck_mecha_params(struct serializer *obj,
583 CK_MECHANISM_PTR mechanism)
584 {
585 CK_MECHANISM mecha = { 0 };
586 CK_RV rv = CKR_GENERAL_ERROR;
587
588 memset(obj, 0, sizeof(*obj));
589
590 obj->object = PKCS11_CKO_MECHANISM;
591
592 mecha = *mechanism;
593 obj->type = mecha.mechanism;
594 if (obj->type == PKCS11_UNDEFINED_ID)
595 return CKR_MECHANISM_INVALID;
596
597 switch (mecha.mechanism) {
598 case CKM_GENERIC_SECRET_KEY_GEN:
599 case CKM_AES_KEY_GEN:
600 case CKM_AES_ECB:
601 case CKM_AES_CMAC:
602 case CKM_MD5:
603 case CKM_SHA_1:
604 case CKM_SHA224:
605 case CKM_SHA256:
606 case CKM_SHA384:
607 case CKM_SHA512:
608 case CKM_MD5_HMAC:
609 case CKM_SHA_1_HMAC:
610 case CKM_SHA224_HMAC:
611 case CKM_SHA256_HMAC:
612 case CKM_SHA384_HMAC:
613 case CKM_SHA512_HMAC:
614 case CKM_EC_KEY_PAIR_GEN:
615 case CKM_ECDSA:
616 case CKM_ECDSA_SHA1:
617 case CKM_ECDSA_SHA224:
618 case CKM_ECDSA_SHA256:
619 case CKM_ECDSA_SHA384:
620 case CKM_ECDSA_SHA512:
621 case CKM_RSA_PKCS_KEY_PAIR_GEN:
622 case CKM_RSA_PKCS:
623 case CKM_MD5_RSA_PKCS:
624 case CKM_SHA1_RSA_PKCS:
625 case CKM_SHA224_RSA_PKCS:
626 case CKM_SHA256_RSA_PKCS:
627 case CKM_SHA384_RSA_PKCS:
628 case CKM_SHA512_RSA_PKCS:
629 /* No parameter expected, size shall be 0 */
630 if (mechanism->ulParameterLen)
631 return CKR_MECHANISM_PARAM_INVALID;
632
633 rv = serialize_32b(obj, obj->type);
634 if (rv)
635 return rv;
636
637 return serialize_32b(obj, 0);
638
639 case CKM_AES_CBC:
640 case CKM_AES_CBC_PAD:
641 case CKM_AES_CTS:
642 return serialize_mecha_aes_iv(obj, &mecha);
643
644 case CKM_AES_CTR:
645 return serialize_mecha_aes_ctr(obj, &mecha);
646
647 case CKM_AES_ECB_ENCRYPT_DATA:
648 return serialize_mecha_key_deriv_str(obj, &mecha);
649
650 case CKM_AES_CBC_ENCRYPT_DATA:
651 return serialize_mecha_aes_cbc_encrypt_data(obj, &mecha);
652
653 case CKM_RSA_PKCS_PSS:
654 case CKM_SHA1_RSA_PKCS_PSS:
655 case CKM_SHA256_RSA_PKCS_PSS:
656 case CKM_SHA384_RSA_PKCS_PSS:
657 case CKM_SHA512_RSA_PKCS_PSS:
658 case CKM_SHA224_RSA_PKCS_PSS:
659 return serialize_mecha_rsa_pss_param(obj, &mecha);
660
661 case CKM_RSA_PKCS_OAEP:
662 return serialize_mecha_rsa_oaep_param(obj, &mecha);
663
664 case CKM_AES_CMAC_GENERAL:
665 case CKM_MD5_HMAC_GENERAL:
666 case CKM_SHA_1_HMAC_GENERAL:
667 case CKM_SHA224_HMAC_GENERAL:
668 case CKM_SHA256_HMAC_GENERAL:
669 case CKM_SHA384_HMAC_GENERAL:
670 case CKM_SHA512_HMAC_GENERAL:
671 return serialize_mecha_mac_general_param(obj, &mecha);
672
673 default:
674 return CKR_MECHANISM_INVALID;
675 }
676 }
677