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