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