xref: /optee_os/ta/pkcs11/src/serializer.c (revision bd62f6a3abfc4f45cb1ee8b5f28971f63e413a96)
14f8a354fSEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause
24f8a354fSEtienne Carriere /*
34f8a354fSEtienne Carriere  * Copyright (c) 2017-2020, Linaro Limited
44f8a354fSEtienne Carriere  */
54f8a354fSEtienne Carriere 
64f8a354fSEtienne Carriere #include <pkcs11_ta.h>
74f8a354fSEtienne Carriere #include <stdbool.h>
84f8a354fSEtienne Carriere #include <stdint.h>
94f8a354fSEtienne Carriere #include <tee_internal_api.h>
104f8a354fSEtienne Carriere #include <trace.h>
114f8a354fSEtienne Carriere 
123158faf6SEtienne Carriere #include "pkcs11_token.h"
134f8a354fSEtienne Carriere #include "serializer.h"
144f8a354fSEtienne Carriere 
154f8a354fSEtienne Carriere /*
164f8a354fSEtienne Carriere  * Util routines for serializes unformatted arguments in a client memref
174f8a354fSEtienne Carriere  */
184f8a354fSEtienne Carriere void serialargs_init(struct serialargs *args, void *in, size_t size)
194f8a354fSEtienne Carriere {
204f8a354fSEtienne Carriere 	args->start = in;
214f8a354fSEtienne Carriere 	args->next = in;
224f8a354fSEtienne Carriere 	args->size = size;
234f8a354fSEtienne Carriere }
244f8a354fSEtienne Carriere 
254daf39b3SJens Wiklander enum pkcs11_rc serialargs_get(struct serialargs *args, void *out, size_t size)
264f8a354fSEtienne Carriere {
274f8a354fSEtienne Carriere 	if (args->next + size > args->start + args->size) {
284f8a354fSEtienne Carriere 		EMSG("arg too short: full %zd, remain %zd, expect %zd",
294f8a354fSEtienne Carriere 		     args->size, args->size - (args->next - args->start), size);
304f8a354fSEtienne Carriere 		return PKCS11_CKR_ARGUMENTS_BAD;
314f8a354fSEtienne Carriere 	}
324f8a354fSEtienne Carriere 
334f8a354fSEtienne Carriere 	TEE_MemMove(out, args->next, size);
344f8a354fSEtienne Carriere 
354f8a354fSEtienne Carriere 	args->next += size;
364f8a354fSEtienne Carriere 
374f8a354fSEtienne Carriere 	return PKCS11_CKR_OK;
384f8a354fSEtienne Carriere }
394f8a354fSEtienne Carriere 
404daf39b3SJens Wiklander enum pkcs11_rc serialargs_alloc_and_get(struct serialargs *args,
414f8a354fSEtienne Carriere 					void **out, size_t size)
424f8a354fSEtienne Carriere {
434f8a354fSEtienne Carriere 	void *ptr = NULL;
444f8a354fSEtienne Carriere 
454f8a354fSEtienne Carriere 	if (!size) {
464f8a354fSEtienne Carriere 		*out = NULL;
474f8a354fSEtienne Carriere 		return PKCS11_CKR_OK;
484f8a354fSEtienne Carriere 	}
494f8a354fSEtienne Carriere 
504f8a354fSEtienne Carriere 	if (args->next + size > args->start + args->size) {
514f8a354fSEtienne Carriere 		EMSG("arg too short: full %zd, remain %zd, expect %zd",
524f8a354fSEtienne Carriere 		     args->size, args->size - (args->next - args->start), size);
534f8a354fSEtienne Carriere 		return PKCS11_CKR_ARGUMENTS_BAD;
544f8a354fSEtienne Carriere 	}
554f8a354fSEtienne Carriere 
564f8a354fSEtienne Carriere 	ptr = TEE_Malloc(size, TEE_MALLOC_FILL_ZERO);
574f8a354fSEtienne Carriere 	if (!ptr)
584f8a354fSEtienne Carriere 		return PKCS11_CKR_DEVICE_MEMORY;
594f8a354fSEtienne Carriere 
604f8a354fSEtienne Carriere 	TEE_MemMove(ptr, args->next, size);
614f8a354fSEtienne Carriere 
624f8a354fSEtienne Carriere 	args->next += size;
634f8a354fSEtienne Carriere 	*out = ptr;
644f8a354fSEtienne Carriere 
654f8a354fSEtienne Carriere 	return PKCS11_CKR_OK;
664f8a354fSEtienne Carriere }
674f8a354fSEtienne Carriere 
684daf39b3SJens Wiklander enum pkcs11_rc serialargs_get_ptr(struct serialargs *args, void **out,
694daf39b3SJens Wiklander 				  size_t size)
704f8a354fSEtienne Carriere {
714f8a354fSEtienne Carriere 	void *ptr = args->next;
724f8a354fSEtienne Carriere 
734f8a354fSEtienne Carriere 	if (!size) {
744f8a354fSEtienne Carriere 		*out = NULL;
754f8a354fSEtienne Carriere 		return PKCS11_CKR_OK;
764f8a354fSEtienne Carriere 	}
774f8a354fSEtienne Carriere 
784f8a354fSEtienne Carriere 	if (args->next + size > args->start + args->size) {
794f8a354fSEtienne Carriere 		EMSG("arg too short: full %zd, remain %zd, expect %zd",
804f8a354fSEtienne Carriere 		     args->size, args->size - (args->next - args->start), size);
814f8a354fSEtienne Carriere 		return PKCS11_CKR_ARGUMENTS_BAD;
824f8a354fSEtienne Carriere 	}
834f8a354fSEtienne Carriere 
844f8a354fSEtienne Carriere 	args->next += size;
854f8a354fSEtienne Carriere 	*out = ptr;
864f8a354fSEtienne Carriere 
874f8a354fSEtienne Carriere 	return PKCS11_CKR_OK;
884f8a354fSEtienne Carriere }
894f8a354fSEtienne Carriere 
904f8a354fSEtienne Carriere bool serialargs_remaining_bytes(struct serialargs *args)
914f8a354fSEtienne Carriere {
924f8a354fSEtienne Carriere 	return args->next < args->start + args->size;
934f8a354fSEtienne Carriere }
943158faf6SEtienne Carriere 
953158faf6SEtienne Carriere enum pkcs11_rc serialargs_get_session_from_handle(struct serialargs *args,
963158faf6SEtienne Carriere 						  struct pkcs11_client *client,
973158faf6SEtienne Carriere 						  struct pkcs11_session **sess)
983158faf6SEtienne Carriere {
993158faf6SEtienne Carriere 	uint32_t rv = PKCS11_CKR_GENERAL_ERROR;
1003158faf6SEtienne Carriere 	uint32_t session_handle = 0;
1013158faf6SEtienne Carriere 	struct pkcs11_session *session = NULL;
1023158faf6SEtienne Carriere 
1033158faf6SEtienne Carriere 	rv = serialargs_get(args, &session_handle, sizeof(uint32_t));
1043158faf6SEtienne Carriere 	if (rv)
1053158faf6SEtienne Carriere 		return rv;
1063158faf6SEtienne Carriere 
1073158faf6SEtienne Carriere 	session = pkcs11_handle2session(session_handle, client);
1083158faf6SEtienne Carriere 	if (!session)
1093158faf6SEtienne Carriere 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
1103158faf6SEtienne Carriere 
1113158faf6SEtienne Carriere 	*sess = session;
1123158faf6SEtienne Carriere 
1133158faf6SEtienne Carriere 	return PKCS11_CKR_OK;
1143158faf6SEtienne Carriere }
115*bd62f6a3SEtienne Carriere 
116*bd62f6a3SEtienne Carriere enum pkcs11_rc serialize(char **bstart, size_t *blen, void *data, size_t len)
117*bd62f6a3SEtienne Carriere {
118*bd62f6a3SEtienne Carriere 	char *buf = NULL;
119*bd62f6a3SEtienne Carriere 	size_t nlen = 0;
120*bd62f6a3SEtienne Carriere 
121*bd62f6a3SEtienne Carriere 	if (ADD_OVERFLOW(*blen, len, &nlen))
122*bd62f6a3SEtienne Carriere 		return PKCS11_CKR_ARGUMENTS_BAD;
123*bd62f6a3SEtienne Carriere 
124*bd62f6a3SEtienne Carriere 	buf = TEE_Realloc(*bstart, nlen);
125*bd62f6a3SEtienne Carriere 	if (!buf)
126*bd62f6a3SEtienne Carriere 		return PKCS11_CKR_DEVICE_MEMORY;
127*bd62f6a3SEtienne Carriere 
128*bd62f6a3SEtienne Carriere 	TEE_MemMove(buf + *blen, data, len);
129*bd62f6a3SEtienne Carriere 
130*bd62f6a3SEtienne Carriere 	*blen = nlen;
131*bd62f6a3SEtienne Carriere 	*bstart = buf;
132*bd62f6a3SEtienne Carriere 
133*bd62f6a3SEtienne Carriere 	return PKCS11_CKR_OK;
134*bd62f6a3SEtienne Carriere }
135*bd62f6a3SEtienne Carriere 
136