| /* |
| * |
| * Copyright 2018-2020 NXP |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /* Common Key store implementation between keystore_a7x and keystore_pc */ |
| |
| /* ************************************************************************** */ |
| /* Includes */ |
| /* ************************************************************************** */ |
| |
| #include <fsl_sss_ftr.h> |
| #include <fsl_sss_keyid_map.h> |
| #include <inttypes.h> |
| #include <nxLog_App.h> |
| #include <stdio.h> |
| #include <string.h> |
| |
| /* ************************************************************************** */ |
| /* Local Defines */ |
| /* ************************************************************************** */ |
| |
| #define KEYSTORE_MAGIC (0xA71C401L) |
| #define KEYSTORE_VERSION (0x0004) |
| |
| /* ************************************************************************** */ |
| /* Structures and Typedefs */ |
| /* ************************************************************************** */ |
| |
| /* ************************************************************************** */ |
| /* Global Variables */ |
| /* ************************************************************************** */ |
| |
| /* ************************************************************************** */ |
| /* Static function declarations */ |
| /* ************************************************************************** */ |
| |
| /* ************************************************************************** */ |
| /* Public Functions */ |
| /* ************************************************************************** */ |
| |
| void ks_common_init_fat(keyStoreTable_t *keystore_shadow, keyIdAndTypeIndexLookup_t *lookup_entires, size_t max_entries) |
| { |
| memset(keystore_shadow, 0, sizeof(*keystore_shadow)); |
| keystore_shadow->magic = KEYSTORE_MAGIC; |
| keystore_shadow->version = KEYSTORE_VERSION; |
| keystore_shadow->maxEntries = (uint16_t)max_entries; |
| keystore_shadow->entries = lookup_entires; |
| memset(keystore_shadow->entries, 0, sizeof(*lookup_entires) * max_entries); |
| } |
| |
| sss_status_t ks_common_update_fat(keyStoreTable_t *keystore_shadow, |
| uint32_t extId, |
| sss_key_part_t key_part, |
| sss_cipher_type_t cipherType, |
| uint8_t intIndex, |
| uint32_t accessPermission, |
| uint16_t keyLen) |
| { |
| sss_status_t retval = kStatus_SSS_Fail; |
| uint32_t i; |
| bool found_entry = FALSE; |
| uint8_t slots_req = 1; |
| uint8_t entries_written = 0; |
| uint16_t keyLen_roundoff = 0; |
| retval = isValidKeyStoreShadow(keystore_shadow); |
| if (retval != kStatus_SSS_Success) |
| goto cleanup; |
| for (i = 0; i < keystore_shadow->maxEntries; i++) { |
| keyIdAndTypeIndexLookup_t *keyEntry = &keystore_shadow->entries[i]; |
| if (keyEntry->extKeyId == extId) { |
| LOG_W("ENTRY already exists 0x%04X", extId); |
| retval = kStatus_SSS_Fail; |
| found_entry = TRUE; |
| break; |
| } |
| } |
| |
| if (key_part == kSSS_KeyPart_Default && (cipherType == kSSS_CipherType_AES || cipherType == kSSS_CipherType_HMAC)) { |
| keyLen_roundoff = ((keyLen / 16) * 16) + ((keyLen % 16) == 0 ? 0 : 16); |
| slots_req = (keyLen_roundoff / 16); |
| } |
| |
| if (!found_entry) { |
| retval = kStatus_SSS_Fail; |
| for (i = 0; i < keystore_shadow->maxEntries; i++) { |
| keyIdAndTypeIndexLookup_t *keyEntry = &keystore_shadow->entries[i]; |
| if (keyEntry->extKeyId == 0) { |
| keyEntry->extKeyId = extId; |
| keyEntry->keyIntIndex = intIndex; |
| keyEntry->keyPart = key_part | ((slots_req - 1) << 4); |
| keyEntry->cipherType = cipherType; |
| //keyEntry->accessPermission = accessPermission; |
| |
| entries_written++; |
| if (entries_written == slots_req) { |
| retval = kStatus_SSS_Success; |
| break; |
| } |
| } |
| } |
| } |
| cleanup: |
| return retval; |
| } |
| |
| sss_status_t ks_common_remove_fat(keyStoreTable_t *keystore_shadow, uint32_t extId) |
| { |
| sss_status_t retval = kStatus_SSS_Fail; |
| uint32_t i; |
| bool found_entry = FALSE; |
| retval = isValidKeyStoreShadow(keystore_shadow); |
| if (retval != kStatus_SSS_Success) |
| goto cleanup; |
| |
| for (i = 0; i < keystore_shadow->maxEntries; i++) { |
| keyIdAndTypeIndexLookup_t *keyEntry = &keystore_shadow->entries[i]; |
| if (keyEntry->extKeyId == extId) { |
| retval = kStatus_SSS_Success; |
| memset(keyEntry, 0, sizeof(keyIdAndTypeIndexLookup_t)); |
| found_entry = TRUE; |
| } |
| } |
| if (!found_entry) { |
| retval = kStatus_SSS_Fail; |
| } |
| cleanup: |
| return retval; |
| } |
| |
| /* ************************************************************************** */ |
| /* Private Functions */ |
| /* ************************************************************************** */ |
| |
| sss_status_t keystore_shadow_From2_To_3(keyStoreTable_t *keystore_shadow) |
| { |
| int i = 0; |
| for (i = 0; i < keystore_shadow->maxEntries; i++) { |
| keyIdAndTypeIndexLookup_t *keyEntry = &keystore_shadow->entries[i]; |
| if (keyEntry != NULL) { |
| uint16_t org_keyIntIndex = (keyEntry->cipherType) | ((keyEntry->keyIntIndex) << 8); |
| |
| switch (keyEntry->keyPart) { |
| case 0: |
| continue; |
| case 1: |
| keyEntry->keyPart = kSSS_KeyPart_Default; |
| keyEntry->cipherType = kSSS_CipherType_Certificate; |
| break; |
| case 2: |
| keyEntry->keyPart = kSSS_KeyPart_Default; |
| keyEntry->cipherType = kSSS_CipherType_AES; |
| break; |
| case 3: |
| keyEntry->keyPart = kSSS_KeyPart_Default; |
| keyEntry->cipherType = kSSS_CipherType_DES; |
| break; |
| case 4: |
| keyEntry->keyPart = kSSS_KeyPart_Default; |
| keyEntry->cipherType = kSSS_CipherType_CMAC; |
| break; |
| #if SSSFTR_RSA |
| case 5: |
| keyEntry->keyPart = kSSS_KeyPart_Public; |
| keyEntry->cipherType = kSSS_CipherType_RSA_CRT; |
| break; |
| #endif |
| case 6: |
| keyEntry->keyPart = kSSS_KeyPart_Public; |
| keyEntry->cipherType = kSSS_CipherType_EC_NIST_P; |
| break; |
| case 7: |
| keyEntry->keyPart = kSSS_KeyPart_Public; |
| keyEntry->cipherType = kSSS_CipherType_EC_MONTGOMERY; |
| break; |
| case 8: |
| keyEntry->keyPart = kSSS_KeyPart_Public; |
| keyEntry->cipherType = kSSS_CipherType_EC_TWISTED_ED; |
| break; |
| #if SSSFTR_RSA |
| case 9: |
| keyEntry->keyPart = kSSS_KeyPart_Private; |
| keyEntry->cipherType = kSSS_CipherType_RSA_CRT; |
| break; |
| #endif |
| case 10: |
| keyEntry->keyPart = kSSS_KeyPart_Private; |
| keyEntry->cipherType = kSSS_CipherType_EC_NIST_P; |
| break; |
| case 11: |
| keyEntry->keyPart = kSSS_KeyPart_Private; |
| keyEntry->cipherType = kSSS_CipherType_EC_MONTGOMERY; |
| break; |
| case 12: |
| keyEntry->keyPart = kSSS_KeyPart_Private; |
| keyEntry->cipherType = kSSS_CipherType_EC_TWISTED_ED; |
| break; |
| #if SSSFTR_RSA |
| case 13: |
| keyEntry->keyPart = kSSS_KeyPart_Pair; |
| keyEntry->cipherType = kSSS_CipherType_RSA_CRT; |
| break; |
| #endif |
| case 14: |
| keyEntry->keyPart = kSSS_KeyPart_Pair; |
| keyEntry->cipherType = kSSS_CipherType_EC_NIST_P; |
| break; |
| case 15: |
| keyEntry->keyPart = kSSS_KeyPart_Pair; |
| keyEntry->cipherType = kSSS_CipherType_EC_MONTGOMERY; |
| break; |
| case 16: |
| keyEntry->keyPart = kSSS_KeyPart_Pair; |
| keyEntry->cipherType = kSSS_CipherType_EC_TWISTED_ED; |
| break; |
| case 17: |
| keyEntry->keyPart = kSSS_KeyPart_Default; |
| keyEntry->cipherType = kSSS_CipherType_UserID; |
| break; |
| default: |
| LOG_E("Error in keystore_shadow_From2_To_3"); |
| return kStatus_SSS_Fail; |
| } |
| |
| keyEntry->keyIntIndex = (uint8_t)org_keyIntIndex; |
| } |
| } |
| |
| return kStatus_SSS_Success; |
| } |
| |
| sss_status_t keystore_shadow_From3_To_4(keyStoreTable_t *keystore_shadow) |
| { |
| int i = 0; |
| for (i = 0; i < keystore_shadow->maxEntries; i++) { |
| keyIdAndTypeIndexLookup_t *keyEntry = &keystore_shadow->entries[i]; |
| if (keyEntry != NULL) { |
| switch (keyEntry->keyPart) { |
| case kSSS_KeyPart_NONE: |
| break; |
| case kSSS_KeyPart_Default: |
| if (keyEntry->cipherType == kSSS_CipherType_Certificate) { |
| keyEntry->cipherType = kSSS_CipherType_Binary; |
| } |
| break; |
| default: |
| LOG_E("Error in keystore_shadow_From3_To_4"); |
| return kStatus_SSS_Fail; |
| } |
| } |
| } |
| |
| return kStatus_SSS_Success; |
| } |
| |
| sss_status_t isValidKeyStoreShadow(keyStoreTable_t *keystore_shadow) |
| { |
| sss_status_t retval = kStatus_SSS_Success; |
| if (keystore_shadow != NULL) { |
| if (keystore_shadow->magic != KEYSTORE_MAGIC) { |
| LOG_E("Mismatch.keystore_shadow->magic and KEYSTORE_MAGIC"); |
| retval = kStatus_SSS_Fail; |
| goto cleanup; |
| } |
| if (keystore_shadow->version != KEYSTORE_VERSION) { |
| if (keystore_shadow->version == 0x0002) { |
| retval = keystore_shadow_From2_To_3(keystore_shadow); |
| retval = keystore_shadow_From3_To_4(keystore_shadow); |
| } |
| else if (keystore_shadow->version == 0x0003) { |
| retval = keystore_shadow_From3_To_4(keystore_shadow); |
| } |
| else { |
| LOG_E(" Version mismatch."); |
| retval = kStatus_SSS_Fail; |
| } |
| goto cleanup; |
| } |
| if (keystore_shadow->maxEntries == 0) { |
| LOG_E("Keystore not yet allocated"); |
| retval = kStatus_SSS_Fail; |
| goto cleanup; |
| } |
| } |
| else { |
| retval = kStatus_SSS_Fail; |
| } |
| cleanup: |
| return retval; |
| } |