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 ret = versal_mbox_alloc(len, src + i * SMALL_PAGE_SIZE, &p); 32 if (ret) 33 return ret; 34 35 arg.data[0] = first | VERSAL_SHA3_384_NEXT_PACKET | len; 36 arg.ibuf[0].mem = p; 37 ret = versal_crypto_request(VERSAL_SHA3_UPDATE, &arg, NULL); 38 if (ret) 39 EMSG("VERSAL_SHA3_UPDATE [%ld, len = %zu]", i, len); 40 41 versal_mbox_free(&p); 42 first = 0; 43 i++; 44 } 45 46 return ret; 47 } 48 49 static TEE_Result get_ciphertext(uint8_t *dst, size_t dst_len) 50 { 51 struct versal_cmd_args arg = { }; 52 struct versal_mbox_mem p = { }; 53 TEE_Result ret = TEE_SUCCESS; 54 55 ret = versal_mbox_alloc(TEE_SHA384_HASH_SIZE, NULL, &p); 56 if (ret) 57 return ret; 58 59 arg.ibuf[0].mem = p; 60 ret = versal_crypto_request(VERSAL_SHA3_UPDATE, &arg, NULL); 61 if (!ret) 62 memcpy(dst, p.buf, MIN(dst_len, (size_t)TEE_SHA384_HASH_SIZE)); 63 else 64 EMSG("VERSAL_SHA3_UPDATE final"); 65 66 versal_mbox_free(&p); 67 68 return ret; 69 } 70 71 TEE_Result versal_sha3_384(const uint8_t *src, size_t src_len, 72 uint8_t *dst, size_t dst_len) 73 { 74 TEE_Result ret = TEE_ERROR_BAD_PARAMETERS; 75 76 if (!src_len || !dst_len || !src || !dst) 77 return ret; 78 79 if (!engine_ready) 80 return TEE_ERROR_BAD_STATE; 81 82 mutex_lock(&lock); 83 84 ret = input_plaintext(src, src_len); 85 if (!ret) 86 ret = get_ciphertext(dst, dst_len); 87 88 mutex_unlock(&lock); 89 90 return ret; 91 } 92 93 static TEE_Result versal_sha3_384_init(void) 94 { 95 uint32_t err = 0; 96 struct versal_cmd_args arg = { }; 97 TEE_Result ret = TEE_SUCCESS; 98 99 arg.data[0] = VERSAL_SHA3_KAT; 100 arg.dlen = 1; 101 102 ret = versal_crypto_request(VERSAL_KAT, &arg, &err); 103 if (!ret) 104 engine_ready = true; 105 106 if (err) { 107 DMSG("SHA3 KAT returned 0x%" PRIx32, err); 108 return TEE_ERROR_GENERIC; 109 } 110 111 return ret; 112 } 113 114 /* Be available for the HUK */ 115 service_init(versal_sha3_384_init); 116