• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }