1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright 2019 Google LLC
7 #include "ufshcd-crypto.h"
9 /* Blk-crypto modes supported by UFS crypto */
10 static const struct ufs_crypto_alg_entry
{
11 enum ufs_crypto_alg ufs_alg
;
12 enum ufs_crypto_key_size ufs_key_size
;
13 } ufs_crypto_algs
[BLK_ENCRYPTION_MODE_MAX
] = {
14 [BLK_ENCRYPTION_MODE_AES_256_XTS
] = {
15 .ufs_alg
= UFS_CRYPTO_ALG_AES_XTS
,
16 .ufs_key_size
= UFS_CRYPTO_KEY_SIZE_256
,
20 static int ufshcd_program_key(struct ufs_hba
*hba
,
21 const union ufs_crypto_cfg_entry
*cfg
, int slot
)
24 u32 slot_offset
= hba
->crypto_cfg_register
+ slot
* sizeof(*cfg
);
27 ufshcd_hold(hba
, false);
29 if (hba
->vops
&& hba
->vops
->program_key
) {
30 err
= hba
->vops
->program_key(hba
, cfg
, slot
);
34 /* Ensure that CFGE is cleared before programming the key */
35 ufshcd_writel(hba
, 0, slot_offset
+ 16 * sizeof(cfg
->reg_val
[0]));
36 for (i
= 0; i
< 16; i
++) {
37 ufshcd_writel(hba
, le32_to_cpu(cfg
->reg_val
[i
]),
38 slot_offset
+ i
* sizeof(cfg
->reg_val
[0]));
41 ufshcd_writel(hba
, le32_to_cpu(cfg
->reg_val
[17]),
42 slot_offset
+ 17 * sizeof(cfg
->reg_val
[0]));
43 /* Dword 16 must be written last */
44 ufshcd_writel(hba
, le32_to_cpu(cfg
->reg_val
[16]),
45 slot_offset
+ 16 * sizeof(cfg
->reg_val
[0]));
51 static int ufshcd_crypto_keyslot_program(struct blk_keyslot_manager
*ksm
,
52 const struct blk_crypto_key
*key
,
55 struct ufs_hba
*hba
= container_of(ksm
, struct ufs_hba
, ksm
);
56 const union ufs_crypto_cap_entry
*ccap_array
= hba
->crypto_cap_array
;
57 const struct ufs_crypto_alg_entry
*alg
=
58 &ufs_crypto_algs
[key
->crypto_cfg
.crypto_mode
];
59 u8 data_unit_mask
= key
->crypto_cfg
.data_unit_size
/ 512;
62 union ufs_crypto_cfg_entry cfg
= {};
65 BUILD_BUG_ON(UFS_CRYPTO_KEY_SIZE_INVALID
!= 0);
66 for (i
= 0; i
< hba
->crypto_capabilities
.num_crypto_cap
; i
++) {
67 if (ccap_array
[i
].algorithm_id
== alg
->ufs_alg
&&
68 ccap_array
[i
].key_size
== alg
->ufs_key_size
&&
69 (ccap_array
[i
].sdus_mask
& data_unit_mask
)) {
75 if (WARN_ON(cap_idx
< 0))
78 cfg
.data_unit_size
= data_unit_mask
;
79 cfg
.crypto_cap_idx
= cap_idx
;
80 cfg
.config_enable
= UFS_CRYPTO_CONFIGURATION_ENABLE
;
82 if (ccap_array
[cap_idx
].algorithm_id
== UFS_CRYPTO_ALG_AES_XTS
) {
83 /* In XTS mode, the blk_crypto_key's size is already doubled */
84 memcpy(cfg
.crypto_key
, key
->raw
, key
->size
/2);
85 memcpy(cfg
.crypto_key
+ UFS_CRYPTO_KEY_MAX_SIZE
/2,
86 key
->raw
+ key
->size
/2, key
->size
/2);
88 memcpy(cfg
.crypto_key
, key
->raw
, key
->size
);
91 err
= ufshcd_program_key(hba
, &cfg
, slot
);
93 memzero_explicit(&cfg
, sizeof(cfg
));
97 static int ufshcd_clear_keyslot(struct ufs_hba
*hba
, int slot
)
100 * Clear the crypto cfg on the device. Clearing CFGE
101 * might not be sufficient, so just clear the entire cfg.
103 union ufs_crypto_cfg_entry cfg
= {};
105 return ufshcd_program_key(hba
, &cfg
, slot
);
108 static int ufshcd_crypto_keyslot_evict(struct blk_keyslot_manager
*ksm
,
109 const struct blk_crypto_key
*key
,
112 struct ufs_hba
*hba
= container_of(ksm
, struct ufs_hba
, ksm
);
114 return ufshcd_clear_keyslot(hba
, slot
);
117 bool ufshcd_crypto_enable(struct ufs_hba
*hba
)
119 if (!(hba
->caps
& UFSHCD_CAP_CRYPTO
))
122 /* Reset might clear all keys, so reprogram all the keys. */
123 blk_ksm_reprogram_all_keys(&hba
->ksm
);
127 static const struct blk_ksm_ll_ops ufshcd_ksm_ops
= {
128 .keyslot_program
= ufshcd_crypto_keyslot_program
,
129 .keyslot_evict
= ufshcd_crypto_keyslot_evict
,
132 static enum blk_crypto_mode_num
133 ufshcd_find_blk_crypto_mode(union ufs_crypto_cap_entry cap
)
137 for (i
= 0; i
< ARRAY_SIZE(ufs_crypto_algs
); i
++) {
138 BUILD_BUG_ON(UFS_CRYPTO_KEY_SIZE_INVALID
!= 0);
139 if (ufs_crypto_algs
[i
].ufs_alg
== cap
.algorithm_id
&&
140 ufs_crypto_algs
[i
].ufs_key_size
== cap
.key_size
) {
144 return BLK_ENCRYPTION_MODE_INVALID
;
148 * ufshcd_hba_init_crypto_capabilities - Read crypto capabilities, init crypto
150 * @hba: Per adapter instance
152 * Return: 0 if crypto was initialized or is not supported, else a -errno value.
154 int ufshcd_hba_init_crypto_capabilities(struct ufs_hba
*hba
)
158 enum blk_crypto_mode_num blk_mode_num
;
161 * Don't use crypto if either the hardware doesn't advertise the
162 * standard crypto capability bit *or* if the vendor specific driver
163 * hasn't advertised that crypto is supported.
165 if (!(hba
->capabilities
& MASK_CRYPTO_SUPPORT
) ||
166 !(hba
->caps
& UFSHCD_CAP_CRYPTO
))
169 hba
->crypto_capabilities
.reg_val
=
170 cpu_to_le32(ufshcd_readl(hba
, REG_UFS_CCAP
));
171 hba
->crypto_cfg_register
=
172 (u32
)hba
->crypto_capabilities
.config_array_ptr
* 0x100;
173 hba
->crypto_cap_array
=
174 devm_kcalloc(hba
->dev
, hba
->crypto_capabilities
.num_crypto_cap
,
175 sizeof(hba
->crypto_cap_array
[0]), GFP_KERNEL
);
176 if (!hba
->crypto_cap_array
) {
181 /* The actual number of configurations supported is (CFGC+1) */
182 err
= blk_ksm_init(&hba
->ksm
,
183 hba
->crypto_capabilities
.config_count
+ 1);
187 hba
->ksm
.ksm_ll_ops
= ufshcd_ksm_ops
;
188 /* UFS only supports 8 bytes for any DUN */
189 hba
->ksm
.max_dun_bytes_supported
= 8;
190 hba
->ksm
.dev
= hba
->dev
;
193 * Cache all the UFS crypto capabilities and advertise the supported
194 * crypto modes and data unit sizes to the block layer.
196 for (cap_idx
= 0; cap_idx
< hba
->crypto_capabilities
.num_crypto_cap
;
198 hba
->crypto_cap_array
[cap_idx
].reg_val
=
199 cpu_to_le32(ufshcd_readl(hba
,
201 cap_idx
* sizeof(__le32
)));
202 blk_mode_num
= ufshcd_find_blk_crypto_mode(
203 hba
->crypto_cap_array
[cap_idx
]);
204 if (blk_mode_num
!= BLK_ENCRYPTION_MODE_INVALID
)
205 hba
->ksm
.crypto_modes_supported
[blk_mode_num
] |=
206 hba
->crypto_cap_array
[cap_idx
].sdus_mask
* 512;
212 devm_kfree(hba
->dev
, hba
->crypto_cap_array
);
214 /* Indicate that init failed by clearing UFSHCD_CAP_CRYPTO */
215 hba
->caps
&= ~UFSHCD_CAP_CRYPTO
;
220 * ufshcd_init_crypto - Initialize crypto hardware
221 * @hba: Per adapter instance
223 void ufshcd_init_crypto(struct ufs_hba
*hba
)
227 if (!(hba
->caps
& UFSHCD_CAP_CRYPTO
))
230 /* Clear all keyslots - the number of keyslots is (CFGC + 1) */
231 for (slot
= 0; slot
< hba
->crypto_capabilities
.config_count
+ 1; slot
++)
232 ufshcd_clear_keyslot(hba
, slot
);
235 void ufshcd_crypto_setup_rq_keyslot_manager(struct ufs_hba
*hba
,
236 struct request_queue
*q
)
238 if (hba
->caps
& UFSHCD_CAP_CRYPTO
)
239 blk_ksm_register(&hba
->ksm
, q
);
242 void ufshcd_crypto_destroy_keyslot_manager(struct ufs_hba
*hba
)
244 blk_ksm_destroy(&hba
->ksm
);