1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) Foundries Ltd. 2022 4 * Author: Jorge Ramirez <jorge@foundries.io> 5 */ 6 7 #include <drivers/versal_sha3_384.h> 8 #include <initcall.h> 9 #include <ipi.h> 10 #include <mm/core_memprot.h> 11 #include <string.h> 12 13 #define VERSAL_SHA3_384_FIRST_PACKET BIT(30) 14 #define VERSAL_SHA3_384_NEXT_PACKET BIT(31) 15 16 static struct mutex lock = MUTEX_INITIALIZER; 17 static bool engine_ready; 18 19 static TEE_Result input_plaintext(const uint8_t *src, size_t src_len) 20 { 21 uint32_t first = VERSAL_SHA3_384_FIRST_PACKET; 22 struct versal_cmd_args arg = { .dlen = 1, }; 23 struct versal_mbox_mem p = { }; 24 TEE_Result ret = TEE_SUCCESS; 25 size_t len = 0; 26 size_t i = 0; 27 28 while (src_len && !ret) { 29 len = MIN(src_len, SMALL_PAGE_SIZE); 30 src_len -= len; 31 versal_mbox_alloc(len, src + i * SMALL_PAGE_SIZE, &p); 32 33 arg.data[0] = first | VERSAL_SHA3_384_NEXT_PACKET | len; 34 arg.ibuf[0].mem = p; 35 ret = versal_crypto_request(VERSAL_SHA3_UPDATE, &arg, NULL); 36 if (ret) 37 EMSG("VERSAL_SHA3_UPDATE [%ld, len = %zu]", i, len); 38 39 free(p.buf); 40 first = 0; 41 i++; 42 } 43 44 return ret; 45 } 46 47 static TEE_Result get_ciphertext(uint8_t *dst, size_t dst_len) 48 { 49 struct versal_cmd_args arg = { }; 50 struct versal_mbox_mem p = { }; 51 TEE_Result ret = TEE_SUCCESS; 52 53 versal_mbox_alloc(TEE_SHA384_HASH_SIZE, NULL, &p); 54 55 arg.ibuf[0].mem = p; 56 ret = versal_crypto_request(VERSAL_SHA3_UPDATE, &arg, NULL); 57 if (!ret) 58 memcpy(dst, p.buf, MIN(dst_len, (size_t)TEE_SHA384_HASH_SIZE)); 59 else 60 EMSG("VERSAL_SHA3_UPDATE final"); 61 62 free(p.buf); 63 64 return ret; 65 } 66 67 TEE_Result versal_sha3_384(const uint8_t *src, size_t src_len, 68 uint8_t *dst, size_t dst_len) 69 { 70 TEE_Result ret = TEE_ERROR_BAD_PARAMETERS; 71 72 if (!src_len || !dst_len || !src || !dst) 73 return ret; 74 75 if (!engine_ready) 76 return TEE_ERROR_BAD_STATE; 77 78 mutex_lock(&lock); 79 80 ret = input_plaintext(src, src_len); 81 if (!ret) 82 ret = get_ciphertext(dst, dst_len); 83 84 mutex_unlock(&lock); 85 86 return ret; 87 } 88 89 static TEE_Result versal_sha3_384_init(void) 90 { 91 struct versal_cmd_args arg = { }; 92 TEE_Result ret = TEE_SUCCESS; 93 94 ret = versal_crypto_request(VERSAL_SHA3_KAT, &arg, NULL); 95 if (!ret) 96 engine_ready = true; 97 98 return ret; 99 } 100 101 /* Be available for the HUK */ 102 service_init(versal_sha3_384_init); 103