Loading drivers/soc/qcom/crypto-qti-hwkm.c +9 −14 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <linux/crypto-qti-common.h> #include <linux/hwkm.h> #include <linux/module.h> #include <linux/kernel.h> #include "crypto-qti-ice-regs.h" #include "crypto-qti-platform.h" Loading @@ -19,6 +20,8 @@ #define QTI_HWKM_INIT_DONE 0x1 #define SLOT_EMPTY_ERROR 0x1000 #define INLINECRYPT_CTX "inline encryption key" #define BYTE_ORDER_VAL 8 union crypto_cfg { __le32 regval[2]; Loading Loading @@ -65,19 +68,10 @@ int crypto_qti_program_key(struct crypto_vops_qti_entry *ice_entry, .km_by_nsec_allowed = true, }; struct hwkm_bsve bsve_kdf = { .enabled = false, .enabled = true, .km_swc_en = true, .km_child_key_policy_en = true, }; u8 ctx[] = { 0xee, 0xb6, 0xa4, 0xc8, 0x6f, 0x22, 0x5f, 0xda, 0x18, 0xff, 0x61, 0x07, 0xfb, 0x88, 0x17, 0x7f, 0xe4, 0x89, 0x8f, 0xed, 0xdb, 0x0c, 0x68, 0xb2, 0x18, 0xe7, 0x58, 0xd0, 0xf7, 0x79, 0x61, 0xad, 0x77, 0xc6, 0x4d, 0x2b, 0x53, 0x93, 0x4f, 0x34, 0xaf, 0x51, 0xab, 0xda, 0x24, 0xa0, 0xa4, 0x76, 0xf4, 0x09, 0xed, 0xa3, 0x2c, 0xa1, 0x8b, 0xcd, 0x01, 0xe7, 0x0a, 0x3e, 0x9d, 0x73, 0xac, 0x96, }; union crypto_cfg cfg; if ((key->size) <= RAW_SECRET_SIZE) { Loading Loading @@ -143,8 +137,9 @@ int crypto_qti_program_key(struct crypto_vops_qti_entry *ice_entry, cmd_kdf.kdf.kdk = GP_KEYSLOT; cmd_kdf.kdf.policy = policy_kdf; cmd_kdf.kdf.bsve = bsve_kdf; cmd_kdf.kdf.sz = 64; memcpy(cmd_kdf.kdf.ctx, ctx, HWKM_MAX_CTX_SIZE); cmd_kdf.kdf.sz = round_up(strlen(INLINECRYPT_CTX), BYTE_ORDER_VAL); memset(cmd_kdf.kdf.ctx, 0, HWKM_MAX_CTX_SIZE); memcpy(cmd_kdf.kdf.ctx, INLINECRYPT_CTX, strlen(INLINECRYPT_CTX)); memset(&cfg, 0, sizeof(cfg)); cfg.dusize = data_unit_mask; Loading drivers/soc/qcom/hwkm.c +49 −9 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ for (retries = 0; !(cond) && (retries < MAX_RETRIES); retries++) #define ICEMEM_SLAVE_TPKEY_VAL 0x192 #define ICEMEM_SLAVE_TPKEY_SLOT 0x92 #define KM_MASTER_TPKEY_SLOT 10 #define BYTE_ORDER_VAL 8 struct hwkm_clk_info { struct list_head list; Loading Loading @@ -436,15 +437,38 @@ static void deserialize_policy(struct hwkm_key_policy *out, out->km_by_spu_allowed = policy->key_management_by_spu_allowed; } static void reverse_key(u8 *key, size_t keylen) static void reverse_bytes(u8 *bytes, size_t len) { size_t left = 0; size_t right = 0; for (left = 0, right = keylen - 1; left < right; left++, right--) { key[left] ^= key[right]; key[right] ^= key[left]; key[left] ^= key[right]; for (left = 0, right = len - 1; left < right; left++, right--) { bytes[left] ^= bytes[right]; bytes[right] ^= bytes[left]; bytes[left] ^= bytes[right]; } } static void reorder_ctx(u8 *ctx, size_t ctxlen) { int i = 0; int len = 0; len = ctxlen / BYTE_ORDER_VAL; /* Reverse ctx at 8 byte boundary */ for (i = 0; i < len; i++) reverse_bytes(ctx + i*BYTE_ORDER_VAL, BYTE_ORDER_VAL); /* * If context is not a multiple of 8 bytes, reverse the last bytes * only. This simulates prepending the last 8 bytes with zeroes, * and then reversing the 8 bytes. */ if (ctxlen % BYTE_ORDER_VAL != 0) { reverse_bytes(ctx + len*BYTE_ORDER_VAL, ctxlen % BYTE_ORDER_VAL); } } Loading Loading @@ -590,6 +614,15 @@ static int qti_handle_system_kdf(const struct hwkm_cmd *cmd_in, serialize_policy(&policy, &cmd_in->kdf.policy); /* * If context is not a multiple of 8 bytes, but a multiple * of 4 bytes, add a zero word at the end, to have a context multiple * of 8 bytes. This is to facilitate the context reordering that will * happen later */ if ((cmd_in->kdf.sz) % BYTE_ORDER_VAL == (BYTE_ORDER_VAL/2)) operation.context_len += 1; WRITE_TO_KDF_PACKET(cmd_ptr, &operation, OPERATION_INFO_LENGTH); WRITE_TO_KDF_PACKET(cmd_ptr, &policy, KEY_POLICY_LENGTH); Loading @@ -599,10 +632,16 @@ static int qti_handle_system_kdf(const struct hwkm_cmd *cmd_in, serialize_kdf_bsve(&bsve, &cmd_in->kdf.bsve, cmd_in->kdf.mks); WRITE_TO_KDF_PACKET(cmd_ptr, &bsve, MAX_BSVE_LENGTH); } else { // Skip the remaining 3 bytes of the current word cmd_ptr += 3 * (sizeof(u8)); // Skip 4 bytes to align to start of context. cmd_ptr += 4 * (sizeof(u8)); } /* * Reorder context to reverse context bytes at the 8 byte * boundary. This is because crypto lib reads at this * boundary when populating the AD. */ reorder_ctx((u8 *) cmd_in->kdf.ctx, cmd_in->kdf.sz); WRITE_TO_KDF_PACKET(cmd_ptr, cmd_in->kdf.ctx, cmd_in->kdf.sz); status = qti_hwkm_run_transaction(ICEMEM_SLAVE, cmd, Loading Loading @@ -724,7 +763,7 @@ static int qti_handle_keyslot_rdwr(const struct hwkm_cmd *cmd_in, cmd_in->rdwr.sz); // Need to reverse the key because the HW expects it in reverse // byte order reverse_key((u8 *) (cmd + COMMAND_KEY_VALUE_IDX), reverse_bytes((u8 *) (cmd + COMMAND_KEY_VALUE_IDX), HWKM_MAX_KEY_SIZE); } Loading @@ -750,7 +789,8 @@ static int qti_handle_keyslot_rdwr(const struct hwkm_cmd *cmd_in, rsp + RESPONSE_KEY_VALUE_IDX, RESPONSE_KEY_LENGTH); // Need to reverse the key because the HW returns it in // reverse byte order reverse_key(rsp_in->rdwr.key, HWKM_MAX_KEY_SIZE); reverse_bytes(rsp_in->rdwr.key, HWKM_MAX_KEY_SIZE); rsp_in->rdwr.sz = RESPONSE_KEY_LENGTH; deserialize_policy(&rsp_in->rdwr.policy, &policy); } Loading Loading
drivers/soc/qcom/crypto-qti-hwkm.c +9 −14 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <linux/crypto-qti-common.h> #include <linux/hwkm.h> #include <linux/module.h> #include <linux/kernel.h> #include "crypto-qti-ice-regs.h" #include "crypto-qti-platform.h" Loading @@ -19,6 +20,8 @@ #define QTI_HWKM_INIT_DONE 0x1 #define SLOT_EMPTY_ERROR 0x1000 #define INLINECRYPT_CTX "inline encryption key" #define BYTE_ORDER_VAL 8 union crypto_cfg { __le32 regval[2]; Loading Loading @@ -65,19 +68,10 @@ int crypto_qti_program_key(struct crypto_vops_qti_entry *ice_entry, .km_by_nsec_allowed = true, }; struct hwkm_bsve bsve_kdf = { .enabled = false, .enabled = true, .km_swc_en = true, .km_child_key_policy_en = true, }; u8 ctx[] = { 0xee, 0xb6, 0xa4, 0xc8, 0x6f, 0x22, 0x5f, 0xda, 0x18, 0xff, 0x61, 0x07, 0xfb, 0x88, 0x17, 0x7f, 0xe4, 0x89, 0x8f, 0xed, 0xdb, 0x0c, 0x68, 0xb2, 0x18, 0xe7, 0x58, 0xd0, 0xf7, 0x79, 0x61, 0xad, 0x77, 0xc6, 0x4d, 0x2b, 0x53, 0x93, 0x4f, 0x34, 0xaf, 0x51, 0xab, 0xda, 0x24, 0xa0, 0xa4, 0x76, 0xf4, 0x09, 0xed, 0xa3, 0x2c, 0xa1, 0x8b, 0xcd, 0x01, 0xe7, 0x0a, 0x3e, 0x9d, 0x73, 0xac, 0x96, }; union crypto_cfg cfg; if ((key->size) <= RAW_SECRET_SIZE) { Loading Loading @@ -143,8 +137,9 @@ int crypto_qti_program_key(struct crypto_vops_qti_entry *ice_entry, cmd_kdf.kdf.kdk = GP_KEYSLOT; cmd_kdf.kdf.policy = policy_kdf; cmd_kdf.kdf.bsve = bsve_kdf; cmd_kdf.kdf.sz = 64; memcpy(cmd_kdf.kdf.ctx, ctx, HWKM_MAX_CTX_SIZE); cmd_kdf.kdf.sz = round_up(strlen(INLINECRYPT_CTX), BYTE_ORDER_VAL); memset(cmd_kdf.kdf.ctx, 0, HWKM_MAX_CTX_SIZE); memcpy(cmd_kdf.kdf.ctx, INLINECRYPT_CTX, strlen(INLINECRYPT_CTX)); memset(&cfg, 0, sizeof(cfg)); cfg.dusize = data_unit_mask; Loading
drivers/soc/qcom/hwkm.c +49 −9 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ for (retries = 0; !(cond) && (retries < MAX_RETRIES); retries++) #define ICEMEM_SLAVE_TPKEY_VAL 0x192 #define ICEMEM_SLAVE_TPKEY_SLOT 0x92 #define KM_MASTER_TPKEY_SLOT 10 #define BYTE_ORDER_VAL 8 struct hwkm_clk_info { struct list_head list; Loading Loading @@ -436,15 +437,38 @@ static void deserialize_policy(struct hwkm_key_policy *out, out->km_by_spu_allowed = policy->key_management_by_spu_allowed; } static void reverse_key(u8 *key, size_t keylen) static void reverse_bytes(u8 *bytes, size_t len) { size_t left = 0; size_t right = 0; for (left = 0, right = keylen - 1; left < right; left++, right--) { key[left] ^= key[right]; key[right] ^= key[left]; key[left] ^= key[right]; for (left = 0, right = len - 1; left < right; left++, right--) { bytes[left] ^= bytes[right]; bytes[right] ^= bytes[left]; bytes[left] ^= bytes[right]; } } static void reorder_ctx(u8 *ctx, size_t ctxlen) { int i = 0; int len = 0; len = ctxlen / BYTE_ORDER_VAL; /* Reverse ctx at 8 byte boundary */ for (i = 0; i < len; i++) reverse_bytes(ctx + i*BYTE_ORDER_VAL, BYTE_ORDER_VAL); /* * If context is not a multiple of 8 bytes, reverse the last bytes * only. This simulates prepending the last 8 bytes with zeroes, * and then reversing the 8 bytes. */ if (ctxlen % BYTE_ORDER_VAL != 0) { reverse_bytes(ctx + len*BYTE_ORDER_VAL, ctxlen % BYTE_ORDER_VAL); } } Loading Loading @@ -590,6 +614,15 @@ static int qti_handle_system_kdf(const struct hwkm_cmd *cmd_in, serialize_policy(&policy, &cmd_in->kdf.policy); /* * If context is not a multiple of 8 bytes, but a multiple * of 4 bytes, add a zero word at the end, to have a context multiple * of 8 bytes. This is to facilitate the context reordering that will * happen later */ if ((cmd_in->kdf.sz) % BYTE_ORDER_VAL == (BYTE_ORDER_VAL/2)) operation.context_len += 1; WRITE_TO_KDF_PACKET(cmd_ptr, &operation, OPERATION_INFO_LENGTH); WRITE_TO_KDF_PACKET(cmd_ptr, &policy, KEY_POLICY_LENGTH); Loading @@ -599,10 +632,16 @@ static int qti_handle_system_kdf(const struct hwkm_cmd *cmd_in, serialize_kdf_bsve(&bsve, &cmd_in->kdf.bsve, cmd_in->kdf.mks); WRITE_TO_KDF_PACKET(cmd_ptr, &bsve, MAX_BSVE_LENGTH); } else { // Skip the remaining 3 bytes of the current word cmd_ptr += 3 * (sizeof(u8)); // Skip 4 bytes to align to start of context. cmd_ptr += 4 * (sizeof(u8)); } /* * Reorder context to reverse context bytes at the 8 byte * boundary. This is because crypto lib reads at this * boundary when populating the AD. */ reorder_ctx((u8 *) cmd_in->kdf.ctx, cmd_in->kdf.sz); WRITE_TO_KDF_PACKET(cmd_ptr, cmd_in->kdf.ctx, cmd_in->kdf.sz); status = qti_hwkm_run_transaction(ICEMEM_SLAVE, cmd, Loading Loading @@ -724,7 +763,7 @@ static int qti_handle_keyslot_rdwr(const struct hwkm_cmd *cmd_in, cmd_in->rdwr.sz); // Need to reverse the key because the HW expects it in reverse // byte order reverse_key((u8 *) (cmd + COMMAND_KEY_VALUE_IDX), reverse_bytes((u8 *) (cmd + COMMAND_KEY_VALUE_IDX), HWKM_MAX_KEY_SIZE); } Loading @@ -750,7 +789,8 @@ static int qti_handle_keyslot_rdwr(const struct hwkm_cmd *cmd_in, rsp + RESPONSE_KEY_VALUE_IDX, RESPONSE_KEY_LENGTH); // Need to reverse the key because the HW returns it in // reverse byte order reverse_key(rsp_in->rdwr.key, HWKM_MAX_KEY_SIZE); reverse_bytes(rsp_in->rdwr.key, HWKM_MAX_KEY_SIZE); rsp_in->rdwr.sz = RESPONSE_KEY_LENGTH; deserialize_policy(&rsp_in->rdwr.policy, &policy); } Loading