1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright 2022-2024 HiSilicon Limited. 4 * Kunpeng hardware accelerator sec hmac algorithm implementation. 5 */ 6 7 #include <drvcrypt_mac.h> 8 #include <initcall.h> 9 #include <sec_hash.h> 10 #include <sec_main.h> 11 12 static struct crypto_hmac *to_hmac_ctx(struct crypto_mac_ctx *ctx) 13 { 14 return container_of(ctx, struct crypto_hmac, hmac_op); 15 } 16 17 static TEE_Result sec_hmac_initialize(struct crypto_mac_ctx *ctx, 18 const uint8_t *key, size_t len) 19 { 20 struct crypto_hmac *hash = NULL; 21 struct hashctx *hash_ctx = NULL; 22 23 if (!ctx || !key) { 24 EMSG("Input ctx is NULL"); 25 return TEE_ERROR_BAD_PARAMETERS; 26 } 27 28 hash = to_hmac_ctx(ctx); 29 hash_ctx = hash->ctx; 30 31 return hisi_sec_digest_ctx_init(hash_ctx, key, len); 32 } 33 34 static TEE_Result sec_hmac_do_update(struct crypto_mac_ctx *ctx, 35 const uint8_t *data, size_t len) 36 { 37 struct crypto_hmac *hash = NULL; 38 struct hashctx *hashctx = NULL; 39 40 if (!len) { 41 IMSG("This is 0 len task, skip"); 42 return TEE_SUCCESS; 43 } 44 45 if (!ctx || (!data && len)) { 46 EMSG("Invalid input parameters"); 47 return TEE_ERROR_BAD_PARAMETERS; 48 } 49 50 hash = to_hmac_ctx(ctx); 51 hashctx = hash->ctx; 52 53 return hisi_sec_digest_do_update(hashctx, data, len); 54 } 55 56 static TEE_Result sec_hmac_do_final(struct crypto_mac_ctx *ctx, uint8_t *digest, 57 size_t len) 58 { 59 struct crypto_hmac *hash = to_hmac_ctx(ctx); 60 struct hashctx *hash_ctx = hash->ctx; 61 62 return hisi_sec_digest_do_final(hash_ctx, digest, len); 63 } 64 65 static void sec_hmac_ctx_free(struct crypto_mac_ctx *ctx) 66 { 67 struct crypto_hmac *hash = NULL; 68 struct hashctx *hash_ctx = NULL; 69 70 if (!ctx) 71 return; 72 73 hash = to_hmac_ctx(ctx); 74 hash_ctx = hash->ctx; 75 if (!hash_ctx) 76 return; 77 78 memzero_explicit(hash_ctx->key, hash_ctx->key_len); 79 hisi_sec_digest_ctx_free(hash_ctx); 80 81 hash->ctx = NULL; 82 83 free(hash); 84 } 85 86 static void sec_hmac_copy_state(struct crypto_mac_ctx *out_ctx, 87 struct crypto_mac_ctx *in_ctx) 88 { 89 struct crypto_hmac *out_hash = NULL; 90 struct crypto_hmac *in_hash = NULL; 91 struct hashctx *out_hash_ctx = NULL; 92 struct hashctx *in_hash_ctx = NULL; 93 94 if (!out_ctx || !in_ctx) { 95 EMSG("Invalid input parameters"); 96 return; 97 } 98 99 out_hash = to_hmac_ctx(out_ctx); 100 in_hash = to_hmac_ctx(in_ctx); 101 102 out_hash_ctx = out_hash->ctx; 103 in_hash_ctx = in_hash->ctx; 104 105 hisi_sec_digest_copy_state(out_hash_ctx, in_hash_ctx); 106 } 107 108 static struct crypto_mac_ops hash_ops = { 109 .init = sec_hmac_initialize, 110 .update = sec_hmac_do_update, 111 .final = sec_hmac_do_final, 112 .free_ctx = sec_hmac_ctx_free, 113 .copy_state = sec_hmac_copy_state, 114 }; 115 116 static TEE_Result sec_hmac_ctx_allocate(struct crypto_mac_ctx **ctx, 117 uint32_t algo) 118 { 119 struct crypto_hmac *hash = NULL; 120 struct hashctx *hash_ctx = NULL; 121 TEE_Result ret = TEE_SUCCESS; 122 123 if (!ctx) { 124 EMSG("Ctx is NULL"); 125 return TEE_ERROR_BAD_PARAMETERS; 126 } 127 128 hash = calloc(1, sizeof(*hash)); 129 if (!hash) { 130 EMSG("Fail to alloc hash"); 131 return TEE_ERROR_OUT_OF_MEMORY; 132 } 133 134 hash_ctx = calloc(1, sizeof(*hash_ctx)); 135 if (!hash_ctx) { 136 EMSG("Fail to alloc hashctx"); 137 ret = TEE_ERROR_OUT_OF_MEMORY; 138 goto free_hash; 139 } 140 141 ret = hisi_sec_hash_ctx_init(hash_ctx, algo); 142 if (ret) 143 goto free_ctx; 144 145 hash->hmac_op.ops = &hash_ops; 146 hash->ctx = hash_ctx; 147 *ctx = &hash->hmac_op; 148 149 return 0; 150 151 free_ctx: 152 free(hash_ctx); 153 free_hash: 154 free(hash); 155 156 return ret; 157 } 158 159 static TEE_Result sec_hmac_init(void) 160 { 161 TEE_Result ret = TEE_SUCCESS; 162 163 ret = drvcrypt_register_hmac(&sec_hmac_ctx_allocate); 164 if (ret) 165 EMSG("Sec hmac register to crypto fail"); 166 167 return ret; 168 } 169 driver_init(sec_hmac_init); 170