1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: KV Storage Library key access module implementation
15 */
16
17 #include "nv_key.h"
18 #include "string.h"
19 #include "nv_porting.h"
20 #include "uapi_crc.h"
21 #include "nv_nvregion.h"
22 #include "common_def.h"
23
24 #define KV_CLEARTEXT_PADDING_SIZE (1UL << 2) /* Currently these both need to be a power of 2... */
25 #define KV_CIPHERTEXT_PADDING_SIZE (1UL << 4) /* ...due to implementation of kv_padded_length */
26 #define kv_padded_length(d, s) (((d) + ((s) - 1)) & ~((s) - 1))
27 #define kv_padded_cleartext_length(d) kv_padded_length(d, KV_CLEARTEXT_PADDING_SIZE)
28 #define kv_padded_ciphertext_length(d) kv_padded_length(d, KV_CIPHERTEXT_PADDING_SIZE)
29 #define KV_COPY_SIZE_ALIGN 32
30
31 uint8_t g_nv_header_magic = KV_KEY_MAGIC;
32 /* 0xFF is initial value */
33 static kv_key_header_t g_header_cmp = {0xFF, 0xFF, 0xFFFF, 0xFF, 0xFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFFFFFF};
34
35 /* IOT-16672 Use ROM Lib function instead (enhanced to support KV requirements, as here) */
kv_key_helper_copy_flash(uint32_t dest_location,uint32_t src_location,uint16_t length)36 errcode_t kv_key_helper_copy_flash(uint32_t dest_location, uint32_t src_location, uint16_t length)
37 {
38 if (length == 0) {
39 return ERRCODE_NV_ZERO_LENGTH_COPY;
40 }
41 uint32_t src_addr = src_location - FLASH_PHYSICAL_ADDR_START;
42 uint16_t length_rounded = length & ~(KV_COPY_SIZE_ALIGN - 1);
43 uint16_t length_remainder = length & (KV_COPY_SIZE_ALIGN - 1);
44 uint16_t dest_offset = 0;
45 while (length_rounded > 0) {
46 if (kv_flash_read((uint32_t)(uintptr_t)src_addr, KV_COPY_SIZE_ALIGN,
47 (uint8_t *)(uintptr_t)(dest_location + dest_offset)) != ERRCODE_SUCC) {
48 return ERRCODE_NV_READ_FLASH_ERR;
49 }
50 dest_offset += KV_COPY_SIZE_ALIGN;
51 src_addr += KV_COPY_SIZE_ALIGN;
52 length_rounded -= KV_COPY_SIZE_ALIGN;
53 }
54
55 if (length_remainder > 0) {
56 if (kv_flash_read((uint32_t)(uintptr_t)src_addr, length_remainder,
57 (uint8_t *)(uintptr_t)(dest_location + dest_offset)) != ERRCODE_SUCC) {
58 return ERRCODE_NV_READ_FLASH_ERR;
59 }
60 }
61 return ERRCODE_SUCC;
62 }
63
64 #ifdef CONFIG_NV_SUPPORT_SINGLE_CORE_SYSTEM
kv_key_direct_write_flash(uint32_t dest,uint32_t length,const uint8_t * src)65 errcode_t kv_key_direct_write_flash(uint32_t dest, uint32_t length, const uint8_t *src)
66 {
67 uint32_t dest_w = dest;
68 if ((dest >= FLASH_PHYSICAL_ADDR_START) &&
69 ((dest + length) <= FLASH_PHYSICAL_ADDR_END)) {
70 dest_w -= FLASH_PHYSICAL_ADDR_START;
71 } else {
72 return ERRCODE_FLASH_INVALID_PARAM_BEYOND_ADDR;
73 }
74
75 if (kv_flash_write(dest_w, length, src, false) != ERRCODE_SUCC) {
76 return ERRCODE_NV_READ_FLASH_ERR;
77 }
78
79 return ERRCODE_SUCC;
80 }
81
kv_key_direct_erase_flash(uint32_t dest,const uint32_t size)82 errcode_t kv_key_direct_erase_flash(uint32_t dest, const uint32_t size)
83 {
84 uint32_t dest_w = dest;
85 if ((dest >= FLASH_PHYSICAL_ADDR_START) &&
86 ((dest + size) <= FLASH_PHYSICAL_ADDR_END)) {
87 dest_w -= FLASH_PHYSICAL_ADDR_START;
88 } else {
89 return ERRCODE_FLASH_INVALID_PARAM_BEYOND_ADDR;
90 }
91
92 if (kv_flash_erase(dest_w, size) != ERRCODE_SUCC) {
93 return ERRCODE_FAIL;
94 }
95
96 return ERRCODE_SUCC;
97 }
98 #endif
99
kv_key_write_flash(uint32_t dest,uint32_t length,const uint8_t * src)100 errcode_t kv_key_write_flash(uint32_t dest, uint32_t length, const uint8_t *src)
101 {
102 #ifdef CONFIG_NV_SUPPORT_SINGLE_CORE_SYSTEM
103 return kv_key_direct_write_flash(dest, length, src);
104 #else
105 return flash_task_drv_write(dest, length, src);
106 #endif
107 }
108
kv_key_erase_flash(uint32_t dest,const uint32_t size)109 errcode_t kv_key_erase_flash(uint32_t dest, const uint32_t size)
110 {
111 #ifdef CONFIG_NV_SUPPORT_SINGLE_CORE_SYSTEM
112 return kv_key_direct_erase_flash(dest, size);
113 #else
114 return flash_task_drv_erase(dest, size);
115 #endif
116 }
117
118 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
kv_key_decode_flash(uintptr_t dest,const uintptr_t src,uint32_t length,uint32_t crypto_handle)119 STATIC errcode_t kv_key_decode_flash(uintptr_t dest, const uintptr_t src, uint32_t length, uint32_t crypto_handle)
120 {
121 errcode_t ret;
122 uint8_t *kv_padded_data = NULL;
123
124 uint32_t padded_length = kv_key_padded_data_length(KV_ATTRIBUTE_ENCRYPTED, (uint16_t)length);
125 if (padded_length == length) {
126 ret = kv_key_helper_copy_flash((uint32_t)dest, (uint32_t)src, (uint16_t)length);
127 if (ret == ERRCODE_SUCC) {
128 return nv_crypto_decode(crypto_handle, dest, dest, length);
129 } else {
130 return ret;
131 }
132 } else {
133 kv_padded_data = (uint8_t *)kv_malloc(padded_length);
134 if (kv_padded_data == NULL) {
135 return ERRCODE_MALLOC;
136 }
137 ret = kv_key_helper_copy_flash((uint32_t)(uintptr_t)kv_padded_data, (uint32_t)(uintptr_t)src,
138 (uint16_t)padded_length);
139 if (ret != ERRCODE_SUCC) {
140 goto end;
141 }
142 ret = nv_crypto_decode(crypto_handle, (uintptr_t)kv_padded_data, (uintptr_t)kv_padded_data, padded_length);
143 if (ret != ERRCODE_SUCC) {
144 goto end;
145 }
146 if (memcpy_s((void *)dest, length, kv_padded_data, length) != EOK) {
147 ret = ERRCODE_MEMCPY;
148 goto end;
149 }
150 }
151 end:
152 kv_free(kv_padded_data);
153 return ret;
154 }
155 #endif
156
kv_key_read_data_from_flash(uintptr_t dest,const uintptr_t src,uint32_t length,uint32_t crypto_handle)157 STATIC errcode_t kv_key_read_data_from_flash(uintptr_t dest, const uintptr_t src, uint32_t length,
158 uint32_t crypto_handle)
159 {
160 if (crypto_handle == INVAILD_CRYPTO_HANDLE) {
161 /* Decrypt not required, just return */
162 return kv_key_helper_copy_flash((uint32_t)dest, (uint32_t)src, (uint16_t)length);
163 } else {
164 /* Data needs decrypting */
165 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
166 return kv_key_decode_flash(dest, src, length, crypto_handle);
167 #else
168 return ERRCODE_FAIL;
169 #endif
170 }
171 }
172
kv_key_read_data(kv_key_handle_t * key,uint8_t * dest_location)173 errcode_t kv_key_read_data(kv_key_handle_t *key, uint8_t *dest_location)
174 {
175 errcode_t res = ERRCODE_SUCC;
176 uint32_t crypto_handle = INVAILD_CRYPTO_HANDLE;
177 uint32_t key_data_offset = 0;
178 uint32_t key_data_location = (uint32_t)(uintptr_t)key->key_location + (uint32_t)sizeof(kv_key_header_t);
179 uint32_t decryptable_data_len = key->header.length;
180 /* Check whether data is encrypted */
181 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
182 if (key->header.enc_key == AES_KDFKEY_SDRK_TYPE) {
183 /* Read key data, using AES engine if encrypted */
184 res = nv_crypto_claim_aes(&crypto_handle, &(key->header));
185 if (res != ERRCODE_SUCC) {
186 nv_crypto_release_aes(crypto_handle);
187 return res;
188 }
189 }
190 #endif
191
192 /* Read key data, using AES engine if encrypted */
193 while (key_data_offset < decryptable_data_len) {
194 uint32_t chunk_len = uapi_min(NV_KEY_DATA_CHUNK_LEN, decryptable_data_len - key_data_offset);
195
196 res = kv_key_read_data_from_flash((uintptr_t)(dest_location + key_data_offset),
197 (uintptr_t)key_data_location + key_data_offset,
198 chunk_len, crypto_handle);
199 if (res != ERRCODE_SUCC) {
200 break;
201 }
202 key_data_offset += chunk_len;
203 }
204 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
205 if (crypto_handle != INVAILD_CRYPTO_HANDLE) {
206 nv_crypto_release_aes(crypto_handle);
207 }
208 #endif
209 return res;
210 }
211
kv_helper_compare_key_data_chunks(const kv_key_handle_t * key,const uint8_t * compare_data,kv_helper_compare_key_data_info_t * info)212 STATIC errcode_t kv_helper_compare_key_data_chunks(const kv_key_handle_t *key, const uint8_t *compare_data,
213 kv_helper_compare_key_data_info_t *info)
214 {
215 errcode_t res = ERRCODE_SUCC;
216
217 uintptr_t key_data_location = (uintptr_t)key->key_location + (uintptr_t)sizeof(kv_key_header_t);
218 uint32_t key_data_offset = 0;
219 while (key_data_offset < key->header.length) {
220 const uint16_t chunk_len = (uint16_t)uapi_min(NV_KEY_DATA_CHUNK_LEN, key->header.length - key_data_offset);
221 res = kv_key_read_data_from_flash((uintptr_t)info->key_data_chunk, (key_data_location + key_data_offset),
222 chunk_len, info->crypto_handle);
223 if (res != ERRCODE_SUCC) {
224 break;
225 }
226
227 uint32_t compare_length = uapi_min(chunk_len, key->header.length - key_data_offset);
228 if (info->compare_data_chunk != NULL) {
229 /* Compare data in flash */
230 res = kv_key_helper_copy_flash((uint32_t)(uintptr_t)info->compare_data_chunk,
231 (uint32_t)(uintptr_t)compare_data + key_data_offset,
232 (uint16_t)compare_length);
233 if (res != ERRCODE_SUCC) {
234 break;
235 }
236 if (memcmp(info->key_data_chunk, info->compare_data_chunk, compare_length) != 0) {
237 return ERRCODE_NV_DATA_MISMATCH;
238 }
239 } else {
240 /* Compare data in RAM */
241 if (memcmp(info->key_data_chunk, compare_data + key_data_offset, compare_length) != 0) {
242 return ERRCODE_NV_DATA_MISMATCH;
243 }
244 }
245 key_data_offset += chunk_len;
246 }
247
248 return res;
249 }
250
kv_helper_compare_key_data(kv_key_handle_t * key,const uint8_t * compare_data,uint16_t compare_length)251 errcode_t kv_helper_compare_key_data(kv_key_handle_t *key, const uint8_t *compare_data, uint16_t compare_length)
252 {
253 kv_helper_compare_key_data_info_t info = {INVAILD_CRYPTO_HANDLE, NULL, NULL};
254 errcode_t res;
255
256 if (key->header.length != compare_length) {
257 return ERRCODE_NV_LENGTH_MISMATCH;
258 }
259
260 /* Key data *will* be in flash and could be encrypted */
261 info.key_data_chunk = (uint8_t *)kv_malloc(NV_KEY_DATA_CHUNK_LEN);
262 if (info.key_data_chunk == NULL) {
263 return ERRCODE_MALLOC;
264 }
265
266 /* Compare data *could* be in flash and will not be encrypted */
267 if (
268 #ifdef CONFIG_NV_SUPPORT_SINGLE_CORE_SYSTEM
269 ((uintptr_t)(compare_data + compare_length) >= FLASH_PHYSICAL_ADDR_START) &&
270 #endif
271 (uintptr_t)(compare_data + compare_length) <= FLASH_PHYSICAL_ADDR_END) {
272 info.compare_data_chunk = (uint8_t *)kv_malloc(NV_KEY_DATA_CHUNK_LEN);
273 if (info.compare_data_chunk == NULL) {
274 res = ERRCODE_MALLOC;
275 /* Ensure there is not a memory leak */
276 goto ret_free;
277 }
278 }
279
280 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
281 if (key->header.enc_key == AES_KDFKEY_SDRK_TYPE) {
282 /* Read key data, using AES engine if encrypted */
283 res = nv_crypto_claim_aes(&(info.crypto_handle), &(key->header));
284 if (res != ERRCODE_SUCC) {
285 goto ret_free;
286 }
287 }
288 #endif
289
290 res = kv_helper_compare_key_data_chunks(key, compare_data, &info);
291
292 ret_free:
293 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
294 if (info.crypto_handle != INVAILD_CRYPTO_HANDLE) {
295 nv_crypto_release_aes(info.crypto_handle);
296 }
297 #endif
298 kv_free(info.compare_data_chunk);
299 kv_free(info.key_data_chunk);
300 return res;
301 }
302
kv_key_is_erased(const kv_key_handle_t * key)303 bool kv_key_is_erased(const kv_key_handle_t *key)
304 {
305 if ((key->header.magic != g_nv_header_magic) ||
306 (key->header.valid != KV_KEY_VALID) ||
307 (key->header.length == 0xFFFF) ||
308 (key->header.length == 0)) {
309 return true;
310 }
311
312 return false;
313 }
314
kv_key_is_valid(kv_key_handle_t * key)315 bool kv_key_is_valid(kv_key_handle_t *key)
316 {
317 bool res = kv_key_is_erased(key);
318 if (res == true) {
319 return false;
320 }
321
322 return (kv_key_validation(key, false) == ERRCODE_SUCC);
323 }
324
325 /**
326 * Attempt to match pertinent bits in a key with a search_pattern
327 * @param key_handle Handle of a valid key
328 * @param search_pattern The pattern of bits to match in the key
329 * @param search_mask A mask to select the pertinent bits in the key for matching
330 * @return true if pattern matches, false otherwise
331 */
kv_key_does_pattern_match(const kv_key_handle_t * key,kv_key_id search_pattern,kv_key_id search_mask)332 static errcode_t kv_key_does_pattern_match(const kv_key_handle_t *key, kv_key_id search_pattern, kv_key_id search_mask)
333 {
334 /* Match pertinent bits in the key with the search_pattern */
335 if ((key->header.key_id & search_mask) != search_pattern) {
336 return ERRCODE_NV_SEARCH_PATTERN_MISMATCH;
337 }
338 return ERRCODE_SUCC;
339 }
340
kv_key_does_filter_match(kv_key_handle_t * key,kv_key_filter_t * search_filter)341 errcode_t kv_key_does_filter_match(kv_key_handle_t *key, kv_key_filter_t *search_filter)
342 {
343 /* If no search filter is given then match every key */
344 if (search_filter != NULL) {
345 errcode_t res;
346 res = kv_key_does_pattern_match(key, search_filter->pattern, search_filter->mask);
347 if (res != ERRCODE_SUCC) {
348 return res;
349 }
350
351 if (((uint32_t)search_filter->type & (uint32_t)KV_KEY_FILTER_TYPE_ANY) != (uint32_t)KV_KEY_FILTER_TYPE_ANY) {
352 /* Determine key type */
353 kv_key_filter_type_t key_type = KV_KEY_FILTER_TYPE_NORMAL;
354 if ((((uint32_t)kv_key_attributes(key)) & ((uint32_t)KV_ATTRIBUTE_PERMANENT)) != 0) {
355 key_type = KV_KEY_FILTER_TYPE_PERMANENT;
356 }
357 if (((uint32_t)search_filter->type & (uint32_t)key_type) == 0) {
358 return ERRCODE_NV_SEARCH_KEY_TYPE_MISMATCH;
359 }
360 }
361
362 if (((uint32_t)search_filter->state & (uint32_t)KV_KEY_FILTER_STATE_ANY) != (uint32_t)KV_KEY_FILTER_STATE_ANY) {
363 /* Determine key state */
364 kv_key_filter_state_t key_state = KV_KEY_FILTER_STATE_INVALID;
365 if (kv_key_is_valid(key)) {
366 key_state = KV_KEY_FILTER_STATE_VALID;
367 }
368 if (((uint32_t)search_filter->state & (uint32_t)key_state) == 0) {
369 return ERRCODE_NV_SEARCH_KEY_STATE_MISMATCH;
370 }
371 }
372 }
373
374 return ERRCODE_SUCC;
375 }
376
kv_key_header_is_full_ff(kv_key_header_t * key_header,uint8_t len)377 STATIC bool kv_key_header_is_full_ff(kv_key_header_t *key_header, uint8_t len)
378 {
379 uint8_t cmp_len = (len > (uint8_t)sizeof(kv_key_header_t)) ? ((uint8_t)sizeof(kv_key_header_t)) : len;
380
381 if (memcmp(key_header, &g_header_cmp, cmp_len) == 0) {
382 return true;
383 }
384 return false;
385 }
386
kv_key_get_handle_from_location(kv_key_location key_location,kv_key_handle_t * key)387 errcode_t kv_key_get_handle_from_location(kv_key_location key_location, kv_key_handle_t *key)
388 {
389 key->header.length = 0xFFFF; /* Would not expect a flash read to fail, but just in case... */
390 errcode_t res = kv_key_helper_copy_flash((uint32_t)(uintptr_t)&key->header, (uint32_t)(uintptr_t)key_location,
391 sizeof(kv_key_header_t));
392 if (res != ERRCODE_SUCC) {
393 return res;
394 }
395
396 key->key_location = key_location;
397
398 if (kv_key_header_is_full_ff(&key->header, (uint8_t)sizeof(kv_key_header_t))) {
399 /* Last key has been read */
400 return ERRCODE_NV_KEY_NOT_FOUND;
401 }
402
403 if (g_nv_header_magic == KV_KEY_MAGIC && key->header.magic != KV_KEY_MAGIC) {
404 /* Wrong key has been read */
405 return ERRCODE_NV_INVALID_KEY_HEADER;
406 }
407 return ERRCODE_SUCC;
408 }
409
kv_key_locations_in_same_page(kv_key_location first_key_location,kv_key_location second_key_location)410 errcode_t kv_key_locations_in_same_page(kv_key_location first_key_location, kv_key_location second_key_location)
411 {
412 uintptr_t first_page_location = (uintptr_t)first_key_location & ~(KV_PAGE_SIZE - 1);
413 uintptr_t second_page_location = ((uintptr_t)second_key_location +
414 (uintptr_t)sizeof(kv_key_header_t)) & ~(KV_PAGE_SIZE - 1);
415 if (first_page_location != second_page_location) {
416 return ERRCODE_FAIL;
417 }
418 return ERRCODE_SUCC;
419 }
420
421 #if (CONFIG_NV_SUPPORT_SKIP_CORRUPT_KEY == NV_YES)
kv_key_get_next_magic_position(kv_key_location key_location,kv_key_handle_t * key)422 errcode_t kv_key_get_next_magic_position(kv_key_location key_location, kv_key_handle_t *key)
423 {
424 uint32_t src = (uint32_t)(uintptr_t)key_location;
425 kv_nvregion_area_t* nvregion_area = nv_get_region_area();
426 uint32_t start_page_loc = nvregion_area->nv_data_addr - FLASH_PHYSICAL_ADDR_START;
427 uint32_t next_page_loc = ((((src - start_page_loc) / KV_PAGE_SIZE) + 1) * KV_PAGE_SIZE) + start_page_loc;
428
429 /* 从传入位置的下一位开始读 */
430 src = src + 1;
431 bool found_ending = false;
432 kv_key_location tmp_location;
433
434 for (; src < next_page_loc - sizeof(kv_key_header_t); src++) {
435 (void)memset_s(&(key->header), sizeof(kv_key_header_t), 0, sizeof(kv_key_header_t));
436 if (kv_key_helper_copy_flash((uint32_t)(uintptr_t)&key->header, src, sizeof(kv_key_header_t)) != ERRCODE_SUCC) {
437 return ERRCODE_NV_READ_FLASH_ERR;
438 }
439
440 if (key->header.magic == KV_KEY_MAGIC &&
441 (key->header.valid == KV_KEY_INVALID || key->header.valid == KV_KEY_VALID)) {
442 key->key_location = (kv_key_location)(uintptr_t)src;
443 /* 找到有效的Key */
444 if (kv_key_validate_integrity(key, true) == ERRCODE_SUCC) {
445 nv_log_debug("[NV][magic] Get valid next key (location = 0x%x).\r\n", key->key_location);
446 return ERRCODE_SUCC;
447 }
448 }
449
450 if (kv_key_header_is_full_ff(&key->header, (uint8_t)sizeof(kv_key_header_t))) {
451 /* 找到一块全F区域,暂时标记为数据结尾 */
452 if (!found_ending) {
453 found_ending = true;
454 tmp_location = (kv_key_location)(uintptr_t)src;
455 }
456 /* 若此段为全F,直接跳到下一段进行读取,不以1的步长行进 */
457 src += (uint32_t)sizeof(kv_key_header_t) - 1;
458 } else if (found_ending) {
459 /* 如又找到一块非全F区域,则上次标记的位置不是数据结尾,取消标记 */
460 found_ending = false;
461 }
462 }
463 if (found_ending) {
464 key->key_location = tmp_location;
465 } else {
466 /* 如未找到数据结尾, 则在最后继续查找更短一些的全FF数据 */
467 for (src = next_page_loc - (uint32_t)sizeof(kv_key_header_t); src < next_page_loc; src++) {
468 uint32_t read_len = next_page_loc - src;
469 if (kv_key_helper_copy_flash((uint32_t)(uintptr_t)&key->header, src, (uint16_t)read_len) != ERRCODE_SUCC) {
470 return ERRCODE_NV_READ_FLASH_ERR;
471 }
472 if (kv_key_header_is_full_ff(&key->header, (uint8_t)read_len)) {
473 key->key_location = (kv_key_location)(uintptr_t)src;
474 nv_log_debug("[NV][magic] Get next key on end 2 (location = 0x%x).\r\n", key->key_location);
475 return ERRCODE_NV_KEY_NOT_FOUND;
476 }
477 }
478 key->key_location = (kv_key_location)(uintptr_t)src;
479 }
480
481 return ERRCODE_NV_KEY_NOT_FOUND;
482 }
483
kv_key_get_next_key_from_location(kv_key_location cur_key_loc,kv_key_location next_key_loc,kv_key_handle_t * key)484 STATIC errcode_t kv_key_get_next_key_from_location(kv_key_location cur_key_loc, kv_key_location next_key_loc,
485 kv_key_handle_t *key)
486 {
487 if (kv_key_locations_in_same_page(cur_key_loc, next_key_loc) != ERRCODE_SUCC) {
488 /* Reached the end of the KV page */
489 return ERRCODE_NV_KEY_NOT_FOUND;
490 }
491
492 return kv_key_get_handle_from_location(next_key_loc, key);
493 }
494
kv_key_get_next_handle_with_corrupt_key(kv_key_handle_t * key,kv_key_validate_status_t key_status)495 STATIC errcode_t kv_key_get_next_handle_with_corrupt_key(kv_key_handle_t *key, kv_key_validate_status_t key_status)
496 {
497 kv_key_handle_t cur_key;
498 errcode_t res = ERRCODE_SUCC;
499
500 /* 如果当前KEY是错误Key,直接需要通过magic找到下一个key */
501 if (key_status == KV_KEY_VALIDATE_WRONG) {
502 return kv_key_get_next_magic_position(key->key_location, key);
503 }
504
505 if (kv_key_header_is_full_ff(&key->header, (uint8_t)sizeof(kv_key_header_t))) {
506 /* Last key has been read */
507 return ERRCODE_NV_KEY_NOT_FOUND;
508 }
509
510 if (key->header.magic != KV_KEY_MAGIC) {
511 /* corrupt key has been read, then get next key by magic */
512 nv_log_info("[NV] header magic error(location = 0x%x)! Get next key by magic.\r\n", key->key_location);
513 return kv_key_get_next_magic_position(key->key_location, key);
514 }
515
516 uint16_t offset = kv_key_flash_size(key);
517 kv_key_location next_key_location = (kv_key_location)((uintptr_t)key->key_location + offset);
518
519 (void)memcpy_s(&cur_key, sizeof(kv_key_handle_t), key, sizeof(kv_key_handle_t));
520
521 /* 出现下面两种情况之一时:
522 1. 下一个Key的位置与当前Key不在一个page内
523 2. 下一个key的位置指向数据结尾
524 首先验证当前key,如果当前KEY校验成功,则说明key length是可信的,说明确实找到了数据结尾,返回ERRCODE_NV_KEY_NOT_FOUND;
525 如果当前KEY校验不成功,则说明key length可能是不正确的,则需要通过magic找到下一个key。
526 */
527 res = kv_key_get_next_key_from_location(key->key_location, next_key_location, key);
528 if (res != ERRCODE_SUCC) {
529 if (key_status == KV_KEY_VALIDATE_CORRECT || (kv_key_validate_integrity(&cur_key, true) == ERRCODE_SUCC)) {
530 key->key_location = next_key_location;
531 if (res == ERRCODE_NV_INVALID_KEY_HEADER) {
532 res = ERRCODE_SUCC;
533 }
534 return res;
535 } else {
536 /* 如果当前KEY校验不成功,则说明key length可能是不正确的,则需要通过magic找到下一个KEY */
537 nv_log_info("[NV] validate failed (location = 0x%x)! Get next key by magic.\r\n", cur_key.key_location);
538 return kv_key_get_next_magic_position(cur_key.key_location, key);
539 }
540 }
541
542 return res;
543 }
544 #endif /* #ifdef CONFIG_NV_SUPPORT_SKIP_CORRUPT_KEY */
545
kv_key_get_next_handle_direct(kv_key_handle_t * key)546 STATIC errcode_t kv_key_get_next_handle_direct(kv_key_handle_t *key)
547 {
548 if (key->header.length == 0xFFFF) {
549 /* Last key has been read */
550 return ERRCODE_NV_KEY_NOT_FOUND;
551 }
552
553 uint16_t offset = kv_key_flash_size(key);
554 kv_key_location new_key_location = (kv_key_location)((uintptr_t)key->key_location + offset);
555 if (kv_key_locations_in_same_page(key->key_location, new_key_location) != ERRCODE_SUCC) {
556 /* Reached the end of the KV page */
557 return ERRCODE_NV_KEY_NOT_FOUND;
558 }
559
560 return kv_key_get_handle_from_location(new_key_location, key);
561 }
562
kv_key_get_next_handle(kv_key_handle_t * key,kv_key_validate_status_t key_status)563 errcode_t kv_key_get_next_handle(kv_key_handle_t *key, kv_key_validate_status_t key_status)
564 {
565 unused(key_status);
566 #if (CONFIG_NV_SUPPORT_SKIP_CORRUPT_KEY == NV_YES)
567 if (g_nv_header_magic == KV_KEY_MAGIC) {
568 return kv_key_get_next_handle_with_corrupt_key(key, key_status);
569 } else {
570 return kv_key_get_next_handle_direct(key);
571 }
572 #else
573 return kv_key_get_next_handle_direct(key);
574 #endif
575 }
576
kv_key_fix_header_for_validate(kv_key_header_t * key_header,bool ignor_invalid)577 STATIC void kv_key_fix_header_for_validate(kv_key_header_t *key_header, bool ignor_invalid)
578 {
579 if (ignor_invalid && key_header->valid == KV_KEY_INVALID) {
580 key_header->valid = KV_KEY_VALID;
581 if (g_nv_header_magic == KV_KEY_NO_MAGIC) {
582 key_header->magic = g_nv_header_magic;
583 }
584 }
585 }
586
kv_key_hash_crc_tag_start(const kv_key_handle_t * key,uint32_t * crc_ret)587 STATIC void kv_key_hash_crc_tag_start(const kv_key_handle_t *key, uint32_t *crc_ret)
588 {
589 *crc_ret = 0;
590 if (key->header.enc_key != AES_KDFKEY_SDRK_TYPE) {
591 return;
592 }
593
594 #if ((CONFIG_NV_SUPPORT_ENCRYPT == NV_YES) && (CONFIG_NV_SUPPORT_HASH_FOR_CRYPT == NV_YES))
595 (void)nv_crypto_start_hash();
596 #endif
597 }
598
kv_key_hash_crc_tag_update(const kv_key_handle_t * key,uint8_t * data_chunk,uint32_t data_len,uint32_t * crc_ret)599 STATIC void kv_key_hash_crc_tag_update(const kv_key_handle_t *key, uint8_t *data_chunk,
600 uint32_t data_len, uint32_t *crc_ret)
601 {
602 #if (defined(CONFIG_NV_SUPPORT_CRC16_VERIFY) && (CONFIG_NV_SUPPORT_CRC16_VERIFY == NV_YES))
603 *crc_ret = (uint16_t)uapi_crc16((uint16_t)*crc_ret, data_chunk, data_len);
604 #else
605 *crc_ret = uapi_crc32(*crc_ret, data_chunk, data_len);
606 #endif
607 if (key->header.enc_key != AES_KDFKEY_SDRK_TYPE) {
608 return;
609 }
610
611 #if ((CONFIG_NV_SUPPORT_ENCRYPT == NV_YES) && (CONFIG_NV_SUPPORT_HASH_FOR_CRYPT == NV_YES))
612 nv_crypto_update_hash(data_chunk, data_len);
613 #endif
614 }
615
kv_key_hash_crc_tag_finish(const kv_key_handle_t * key,uint8_t * calculated_hash,uint32_t crc_value,uint32_t crypto_handle)616 STATIC void kv_key_hash_crc_tag_finish(const kv_key_handle_t *key, uint8_t *calculated_hash, uint32_t crc_value,
617 uint32_t crypto_handle)
618 {
619 unused(crypto_handle);
620 uint32_t crc_ret = kv_crc32_swap(crc_value);
621 if (key->header.enc_key != AES_KDFKEY_SDRK_TYPE) {
622 (void)memcpy_s((void *)calculated_hash, KV_CRYPTO_CRC_SIZE, (const void *)&crc_ret, KV_CRYPTO_CRC_SIZE);
623 return;
624 }
625
626 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
627 #if (CONFIG_NV_SUPPORT_HASH_FOR_CRYPT == NV_YES)
628 nv_crypto_complete_hash(calculated_hash);
629 (void)memcpy_s((void *)(calculated_hash + KV_CRYPTO_HASH_SIZE - KV_CRYPTO_CRC_SIZE), KV_CRYPTO_CRC_SIZE,
630 (const void *)&crc_ret, KV_CRYPTO_CRC_SIZE);
631 #else
632 (void)memcpy_s((void *)(calculated_hash + KV_CRYPTO_HASH_SIZE - KV_CRYPTO_CRC_SIZE), KV_CRYPTO_CRC_SIZE,
633 (const void *)&crc_ret, KV_CRYPTO_CRC_SIZE);
634 #endif /* (CONFIG_NV_SUPPORT_HASH_FOR_CRYPT == NV_YES) */
635 #endif /* #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES) */
636 }
637
kv_key_hash_crc_tag_verify(const kv_key_handle_t * key,uint8_t * read_hash_crc,uint8_t * cal_hash_crc,uint32_t crypto_handle,bool only_crc)638 STATIC errcode_t kv_key_hash_crc_tag_verify(const kv_key_handle_t *key, uint8_t *read_hash_crc, uint8_t *cal_hash_crc,
639 uint32_t crypto_handle, bool only_crc)
640 {
641 unused(crypto_handle);
642 unused(only_crc);
643 errcode_t res = ERRCODE_SUCC;
644
645 if (key->header.enc_key != AES_KDFKEY_SDRK_TYPE) {
646 if (memcmp(cal_hash_crc, read_hash_crc, KV_CRYPTO_CRC_SIZE) != 0) {
647 res = ERRCODE_NV_HASH_MISMATCH;
648 }
649 return res;
650 }
651
652 #if (CONFIG_NV_SUPPORT_ENCRYPT != NV_YES)
653 /* 不支持加密的情况下直接返回失败 */
654 return ERRCODE_NV_HASH_MISMATCH;
655 #else
656 if (only_crc) {
657 /* 只校验CRC的场景,校验最后4个字节的CRC(密文的CRC) */
658 if (memcmp(cal_hash_crc + KV_CRYPTO_HASH_SIZE - KV_CRYPTO_CRC_SIZE,
659 read_hash_crc + KV_CRYPTO_HASH_SIZE - KV_CRYPTO_CRC_SIZE, KV_CRYPTO_CRC_SIZE) != 0) {
660 res = ERRCODE_NV_HASH_MISMATCH;
661 }
662 return res;
663 }
664 #if (CONFIG_NV_SUPPORT_HASH_FOR_CRYPT == NV_YES)
665 /* 使用HASH校验的场景,校验HASH的前28个字节 */
666 if (memcmp(cal_hash_crc, read_hash_crc, KV_CRYPTO_HASH_SIZE - KV_CRYPTO_CRC_SIZE) != 0) {
667 res = ERRCODE_NV_HASH_MISMATCH;
668 }
669 return res;
670 #else
671 /* 使用GCM TAG的场景,直接校验16字节的TAG */
672 return nv_crypto_validate_tag(crypto_handle);
673 #endif /* (CONFIG_NV_SUPPORT_HASH_FOR_CRYPT == NV_YES)) */
674 #endif /* #if (CONFIG_NV_SUPPORT_ENCRYPT != NV_YES) */
675 }
676
kv_key_validate_hash_chunks(kv_key_handle_t * key,uint8_t * read_data_chunk,uint8_t * cal_hash_crc,uint32_t crypto_handle,bool ignor_invalid)677 STATIC errcode_t kv_key_validate_hash_chunks(kv_key_handle_t *key, uint8_t *read_data_chunk, uint8_t *cal_hash_crc,
678 uint32_t crypto_handle, bool ignor_invalid)
679 {
680 errcode_t res;
681 kv_key_header_t *key_header = (kv_key_header_t *)read_data_chunk;
682 uintptr_t key_location = (uintptr_t)key->key_location;
683 uint32_t crc_ret = 0;
684
685 uint16_t hash_crc_len = KV_CRYPTO_CRC_SIZE;
686 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
687 if (key->header.enc_key == AES_KDFKEY_SDRK_TYPE) { hash_crc_len = KV_CRYPTO_HASH_SIZE; }
688 #endif
689 kv_key_hash_crc_tag_start(key, &crc_ret);
690
691 /* Read header first, which is never encrypted */
692 res = kv_key_read_data_from_flash((uintptr_t)read_data_chunk, key_location,
693 sizeof(kv_key_header_t), INVAILD_CRYPTO_HANDLE);
694 if (res != ERRCODE_SUCC) {
695 return res;
696 }
697
698 kv_key_fix_header_for_validate(key_header, ignor_invalid);
699
700 kv_key_hash_crc_tag_update(key, read_data_chunk, sizeof(kv_key_header_t), &crc_ret);
701
702 const kv_attributes_t attributes = kv_key_attributes(key);
703 uint32_t decryptable_data_len = kv_key_padded_data_length(attributes, key->header.length);
704 #if (CONFIG_NV_SUPPORT_HASH_FOR_CRYPT == NV_NO)
705 if (crypto_handle != INVAILD_CRYPTO_HANDLE) {
706 /* 在使用GCM TAG时,先读取一次TAG并设置给解密模块 */
707 /* Read key hash, which could be unencrypted */
708 uintptr_t hash_location = key_location + (uintptr_t)sizeof(kv_key_header_t) + (uintptr_t)decryptable_data_len;
709 (void)kv_key_read_data_from_flash((uintptr_t)read_data_chunk, hash_location,
710 KV_CRYPTO_HASH_SIZE, INVAILD_CRYPTO_HANDLE);
711 (void)nv_crypto_set_tag(crypto_handle, read_data_chunk, NV_AES_GCM_TAG_LENGTH);
712 }
713 #endif
714
715 /* Read rest of key data, which could be encrypted */
716 uint32_t key_data_offset = 0;
717 key_location += (uintptr_t)sizeof(kv_key_header_t);
718 while (key_data_offset < decryptable_data_len) {
719 uint32_t chunk_len = uapi_min(NV_KEY_DATA_CHUNK_LEN, decryptable_data_len - key_data_offset);
720
721 res = kv_key_read_data_from_flash((uintptr_t)read_data_chunk, (key_location + key_data_offset),
722 chunk_len, crypto_handle);
723 if (res != ERRCODE_SUCC) {
724 return res;
725 }
726
727 kv_key_hash_crc_tag_update(key, read_data_chunk, chunk_len, &crc_ret);
728 key_data_offset += chunk_len;
729 }
730
731 /* Read key hash, which could be unencrypted */
732 res = kv_key_read_data_from_flash((uintptr_t)read_data_chunk, (key_location + key_data_offset),
733 hash_crc_len, INVAILD_CRYPTO_HANDLE);
734
735 kv_key_hash_crc_tag_finish(key, cal_hash_crc, crc_ret, crypto_handle);
736 return res;
737 }
738
739 /*
740 * 校验KEY的完整性。
741 * 非加密KEY, 校验CRC;
742 * 加密KEY, 如CONFIG_NV_SUPPORT_HASH_FOR_CRYPT为YES,校验明文HASH;
743 * 如CONFIG_NV_SUPPORT_HASH_FOR_CRYPT为NO,校验密文的CRC(CRC存放在16字节Tag之后)。
744 */
kv_key_validate_integrity(kv_key_handle_t * key,bool ignor_invalid)745 errcode_t kv_key_validate_integrity(kv_key_handle_t *key, bool ignor_invalid)
746 {
747 uint32_t crypto_handle = INVAILD_CRYPTO_HANDLE;
748
749 if (key->header.length > NV_NORMAL_KVALUE_MAX_LEN) {
750 return ERRCODE_NV_INVALID_KEY_HEADER;
751 }
752
753 uint8_t *calculated_hash = (uint8_t *)kv_malloc(KV_CRYPTO_HASH_SIZE);
754 if (calculated_hash == NULL) {
755 return ERRCODE_MALLOC;
756 }
757
758 uint8_t *read_data_chunk = (uint8_t *)kv_malloc(NV_KEY_DATA_CHUNK_LEN);
759 if (read_data_chunk == NULL) {
760 kv_free(calculated_hash);
761 return ERRCODE_MALLOC;
762 }
763
764 errcode_t res = kv_key_validate_hash_chunks(key, read_data_chunk, calculated_hash, crypto_handle, ignor_invalid);
765 if (res != ERRCODE_SUCC) {
766 goto err;
767 }
768
769 res = kv_key_hash_crc_tag_verify(key, read_data_chunk, calculated_hash, crypto_handle, true);
770
771 err:
772 kv_free(read_data_chunk);
773 kv_free(calculated_hash);
774 return res;
775 }
776
777 /*
778 * 校验KEY的正确性:
779 * 非加密KEY校验CRC
780 * 加密KEY, 如CONFIG_NV_SUPPORT_HASH_FOR_CRYPT为YES,校验明文HASH;
781 * 如CONFIG_NV_SUPPORT_HASH_FOR_CRYPT为NO,则校验GCM Tag。
782 */
kv_key_validation(kv_key_handle_t * key,bool ignor_invalid)783 errcode_t kv_key_validation(kv_key_handle_t *key, bool ignor_invalid)
784 {
785 errcode_t res;
786 uint32_t crypto_handle = INVAILD_CRYPTO_HANDLE;
787
788 if (key->header.length > NV_NORMAL_KVALUE_MAX_LEN) {
789 return ERRCODE_NV_INVALID_KEY_HEADER;
790 }
791
792 uint8_t *calculated_hash = (uint8_t *)kv_zalloc(KV_CRYPTO_HASH_SIZE);
793 if (calculated_hash == NULL) {
794 return ERRCODE_MALLOC;
795 }
796
797 uint8_t *read_data_chunk = (uint8_t *)kv_zalloc(NV_KEY_DATA_CHUNK_LEN);
798 if (read_data_chunk == NULL) {
799 kv_free(calculated_hash);
800 return ERRCODE_MALLOC;
801 }
802
803 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
804 if (key->header.enc_key != 0) {
805 /* Read key data, using AES engine if encrypted */
806 res = nv_crypto_claim_aes(&crypto_handle, &(key->header));
807 if (res != ERRCODE_SUCC) {
808 goto err;
809 }
810 }
811 #endif
812
813 res = kv_key_validate_hash_chunks(key, read_data_chunk, calculated_hash, crypto_handle, ignor_invalid);
814 if (res != ERRCODE_SUCC) {
815 goto err;
816 }
817
818 res = kv_key_hash_crc_tag_verify(key, read_data_chunk, calculated_hash, crypto_handle, false);
819
820 err:
821 kv_free(read_data_chunk);
822 kv_free(calculated_hash);
823
824 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
825 if (crypto_handle != INVAILD_CRYPTO_HANDLE) {
826 nv_crypto_release_aes(crypto_handle);
827 }
828 #endif
829 return res;
830 }
831
kv_key_attributes(const kv_key_handle_t * key)832 kv_attributes_t kv_key_attributes(const kv_key_handle_t *key)
833 {
834 kv_attributes_t attributes = 0;
835
836 if (key->header.type != KV_KEY_TYPE_NORMAL) {
837 attributes = (kv_attributes_t)((uint32_t)attributes | (uint32_t)KV_ATTRIBUTE_PERMANENT);
838 }
839 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
840 if (key->header.enc_key != 0) {
841 attributes = (kv_attributes_t)((uint32_t)attributes | (uint32_t)KV_ATTRIBUTE_ENCRYPTED);
842 }
843 #endif
844 if (key->header.upgrade != KV_KEY_TYPE_NORMAL) {
845 attributes = (kv_attributes_t)((uint32_t)attributes | (uint32_t)KV_ATTRIBUTE_NON_UPGRADE);
846 }
847 return attributes;
848 }
849
kv_key_padded_data_length(kv_attributes_t attributes,uint16_t unpadded_length)850 uint16_t kv_key_padded_data_length(kv_attributes_t attributes, uint16_t unpadded_length)
851 {
852 unused(attributes);
853 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
854 if (((uint32_t)attributes & (uint32_t)KV_ATTRIBUTE_ENCRYPTED) != 0) {
855 return kv_padded_ciphertext_length(unpadded_length);
856 }
857 #endif
858 return kv_padded_cleartext_length(unpadded_length);
859 }
860
kv_key_flash_size(kv_key_handle_t * key)861 uint16_t kv_key_flash_size(kv_key_handle_t *key)
862 {
863 uint16_t size;
864 kv_attributes_t attributes;
865 uint16_t hash_crc_size = KV_CRYPTO_CRC_SIZE;
866 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
867 if (key->header.enc_key == AES_KDFKEY_SDRK_TYPE) {
868 hash_crc_size = KV_CRYPTO_HASH_SIZE;
869 }
870 #endif
871 size = (uint16_t)sizeof(kv_key_header_t) + hash_crc_size;
872
873 attributes = kv_key_attributes(key);
874 size += kv_key_padded_data_length(attributes, key->header.length);
875
876 return size;
877 }
878
kv_key_build_from_new(kv_key_handle_t * key,const kv_key_details_t * new_key,kv_key_location key_location)879 void kv_key_build_from_new(kv_key_handle_t *key, const kv_key_details_t *new_key, kv_key_location key_location)
880 {
881 key->header.key_id = new_key->key_id;
882 key->header.length = (uint16_t)new_key->kvalue_length;
883 key->header.magic = g_nv_header_magic;
884 key->header.valid = KV_KEY_VALID;
885 key->header.type = KV_KEY_TYPE_NORMAL;
886 if (((uint32_t)new_key->attributes & (uint32_t)KV_ATTRIBUTE_PERMANENT) != 0) {
887 key->header.type = KV_KEY_TYPE_PERMANENT;
888 }
889 key->header.upgrade = KV_KEY_TYPE_NORMAL;
890 if (((uint32_t)new_key->attributes & (uint32_t)KV_ATTRIBUTE_NON_UPGRADE) != 0) {
891 key->header.upgrade = 0;
892 key->header.version = key->header.version + 1;
893 }
894 key->header.enc_key = 0;
895 #if (CONFIG_NV_SUPPORT_ENCRYPT == NV_YES)
896 if (((uint32_t)new_key->attributes & (uint32_t)KV_ATTRIBUTE_ENCRYPTED) != 0) {
897 key->header.enc_key = AES_KDFKEY_SDRK_TYPE;
898 nv_crypto_generate_random(&key->header.rnd);
899 key->header.version = key->header.version + 1;
900 }
901 #endif
902 key->key_location = key_location;
903 }
904
kv_crc32_swap(uint32_t crc)905 uint32_t kv_crc32_swap(uint32_t crc)
906 {
907 return ((crc >> CRC_SWAP_SIZE24) | ((crc >> CRC_SWAP_SIZE8) & 0xFF00) |
908 ((crc << CRC_SWAP_SIZE8) & 0xFF0000) | (crc << CRC_SWAP_SIZE24));
909 }