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 enum pkcs11_rc 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 enum pkcs11_rc 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 enum pkcs11_rc serialargs_get_ptr(struct serialargs *args, void **out, 69 size_t size) 70 { 71 void *ptr = args->next; 72 73 if (!size) { 74 *out = NULL; 75 return PKCS11_CKR_OK; 76 } 77 78 if (args->next + size > args->start + args->size) { 79 EMSG("arg too short: full %zd, remain %zd, expect %zd", 80 args->size, args->size - (args->next - args->start), size); 81 return PKCS11_CKR_ARGUMENTS_BAD; 82 } 83 84 args->next += size; 85 *out = ptr; 86 87 return PKCS11_CKR_OK; 88 } 89 90 bool serialargs_remaining_bytes(struct serialargs *args) 91 { 92 return args->next < args->start + args->size; 93 } 94 95 enum pkcs11_rc serialargs_get_session_from_handle(struct serialargs *args, 96 struct pkcs11_client *client, 97 struct pkcs11_session **sess) 98 { 99 uint32_t rv = PKCS11_CKR_GENERAL_ERROR; 100 uint32_t session_handle = 0; 101 struct pkcs11_session *session = NULL; 102 103 rv = serialargs_get(args, &session_handle, sizeof(uint32_t)); 104 if (rv) 105 return rv; 106 107 session = pkcs11_handle2session(session_handle, client); 108 if (!session) 109 return PKCS11_CKR_SESSION_HANDLE_INVALID; 110 111 *sess = session; 112 113 return PKCS11_CKR_OK; 114 } 115