xref: /optee_os/ta/pkcs11/src/serializer.c (revision ed3fa831cdd6c545bf2813de8aeccc2564387983)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2017-2020, Linaro Limited
4  */
5 
6 #include <pkcs11_ta.h>
7 #include <stdbool.h>
8 #include <stdint.h>
9 #include <tee_internal_api.h>
10 #include <trace.h>
11 
12 #include "pkcs11_token.h"
13 #include "serializer.h"
14 
15 /*
16  * Util routines for serializes unformatted arguments in a client memref
17  */
18 void serialargs_init(struct serialargs *args, void *in, size_t size)
19 {
20 	args->start = in;
21 	args->next = in;
22 	args->size = size;
23 }
24 
25 uint32_t serialargs_get(struct serialargs *args, void *out, size_t size)
26 {
27 	if (args->next + size > args->start + args->size) {
28 		EMSG("arg too short: full %zd, remain %zd, expect %zd",
29 		     args->size, args->size - (args->next - args->start), size);
30 		return PKCS11_CKR_ARGUMENTS_BAD;
31 	}
32 
33 	TEE_MemMove(out, args->next, size);
34 
35 	args->next += size;
36 
37 	return PKCS11_CKR_OK;
38 }
39 
40 uint32_t serialargs_alloc_and_get(struct serialargs *args,
41 				  void **out, size_t size)
42 {
43 	void *ptr = NULL;
44 
45 	if (!size) {
46 		*out = NULL;
47 		return PKCS11_CKR_OK;
48 	}
49 
50 	if (args->next + size > args->start + args->size) {
51 		EMSG("arg too short: full %zd, remain %zd, expect %zd",
52 		     args->size, args->size - (args->next - args->start), size);
53 		return PKCS11_CKR_ARGUMENTS_BAD;
54 	}
55 
56 	ptr = TEE_Malloc(size, TEE_MALLOC_FILL_ZERO);
57 	if (!ptr)
58 		return PKCS11_CKR_DEVICE_MEMORY;
59 
60 	TEE_MemMove(ptr, args->next, size);
61 
62 	args->next += size;
63 	*out = ptr;
64 
65 	return PKCS11_CKR_OK;
66 }
67 
68 uint32_t serialargs_get_ptr(struct serialargs *args, void **out, size_t size)
69 {
70 	void *ptr = args->next;
71 
72 	if (!size) {
73 		*out = NULL;
74 		return PKCS11_CKR_OK;
75 	}
76 
77 	if (args->next + size > args->start + args->size) {
78 		EMSG("arg too short: full %zd, remain %zd, expect %zd",
79 		     args->size, args->size - (args->next - args->start), size);
80 		return PKCS11_CKR_ARGUMENTS_BAD;
81 	}
82 
83 	args->next += size;
84 	*out = ptr;
85 
86 	return PKCS11_CKR_OK;
87 }
88 
89 bool serialargs_remaining_bytes(struct serialargs *args)
90 {
91 	return args->next < args->start + args->size;
92 }
93 
94 enum pkcs11_rc serialargs_get_session_from_handle(struct serialargs *args,
95 						  struct pkcs11_client *client,
96 						  struct pkcs11_session **sess)
97 {
98 	uint32_t rv = PKCS11_CKR_GENERAL_ERROR;
99 	uint32_t session_handle = 0;
100 	struct pkcs11_session *session = NULL;
101 
102 	rv = serialargs_get(args, &session_handle, sizeof(uint32_t));
103 	if (rv)
104 		return rv;
105 
106 	session = pkcs11_handle2session(session_handle, client);
107 	if (!session)
108 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
109 
110 	*sess = session;
111 
112 	return PKCS11_CKR_OK;
113 }
114