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 <arm.h> 8 #include <initcall.h> 9 #include <ipi.h> 10 #include <kernel/panic.h> 11 #include <mm/core_memprot.h> 12 #include <string.h> 13 #include <tee/cache.h> 14 #include <util.h> 15 16 #define SEC_MODULE_SHIFT 8 17 #define SEC_MODULE_ID 5 18 19 #define CRYPTO_API_ID(__x) ((SEC_MODULE_ID << SEC_MODULE_SHIFT) | (__x)) 20 21 static TEE_Result versal_sha3_request(enum versal_crypto_api id, 22 struct versal_cmd_args *arg) 23 { 24 struct versal_ipi_cmd cmd = { }; 25 uint32_t a = 0; 26 uint32_t b = 0; 27 28 cmd.data[0] = CRYPTO_API_ID(id); 29 30 if (arg->data[0]) { 31 /* write */ 32 reg_pair_from_64(virt_to_phys(arg->ibuf[0].mem.buf), &b, &a); 33 cmd.data[1] = a; 34 cmd.data[2] = b; 35 cmd.data[3] = arg->data[0]; 36 37 cmd.ibuf[0].mem = arg->ibuf[0].mem; 38 } else { 39 /* read */ 40 reg_pair_from_64(virt_to_phys(arg->ibuf[0].mem.buf), &b, &a); 41 cmd.data[4] = a; 42 cmd.data[5] = b; 43 44 cmd.ibuf[0].mem = arg->ibuf[0].mem; 45 } 46 47 return versal_mbox_notify(&cmd, NULL, NULL); 48 } 49 50 static TEE_Result versal_aes_update_aad_request(enum versal_crypto_api id, 51 struct versal_cmd_args *arg) 52 { 53 struct versal_ipi_cmd cmd = { }; 54 uint32_t a = 0; 55 uint32_t b = 0; 56 57 reg_pair_from_64(virt_to_phys(arg->ibuf[0].mem.buf), &b, &a); 58 59 cmd.data[0] = CRYPTO_API_ID(id); 60 cmd.data[1] = a; 61 cmd.data[2] = b; 62 cmd.data[3] = arg->data[0]; 63 64 cmd.ibuf[0].mem = arg->ibuf[0].mem; 65 66 return versal_mbox_notify(&cmd, NULL, NULL); 67 } 68 69 TEE_Result versal_crypto_request(enum versal_crypto_api id, 70 struct versal_cmd_args *arg, uint32_t *err) 71 { 72 struct versal_ipi_cmd cmd = { }; 73 uint32_t a = 0; 74 uint32_t b = 0; 75 size_t i = 0; 76 77 if (id == VERSAL_SHA3_UPDATE) 78 return versal_sha3_request(id, arg); 79 80 if (id == VERSAL_AES_UPDATE_AAD) 81 return versal_aes_update_aad_request(id, arg); 82 83 cmd.data[0] = CRYPTO_API_ID(id); 84 for (i = 1; i < arg->dlen + 1; i++) 85 cmd.data[i] = arg->data[i - 1]; 86 87 /* src */ 88 if (!arg->ibuf[0].mem.buf) 89 goto notify; 90 91 reg_pair_from_64(virt_to_phys(arg->ibuf[0].mem.buf), &b, &a); 92 cmd.data[i++] = a; 93 cmd.data[i++] = b; 94 95 /* dst */ 96 if (!arg->ibuf[1].mem.buf) 97 goto cache; 98 99 if (arg->ibuf[1].only_cache) 100 goto cache; 101 102 reg_pair_from_64(virt_to_phys(arg->ibuf[1].mem.buf), &b, &a); 103 cmd.data[i++] = a; 104 cmd.data[i++] = b; 105 cache: 106 for (i = 0; i < VERSAL_MAX_IPI_BUF; i++) 107 cmd.ibuf[i].mem = arg->ibuf[i].mem; 108 notify: 109 return versal_mbox_notify(&cmd, NULL, err); 110 } 111