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