/* * * Copyright 2018-2020 NXP * SPDX-License-Identifier: Apache-2.0 */ /* Common Key store implementation between keystore_a7x and keystore_pc */ /* ************************************************************************** */ /* Includes */ /* ************************************************************************** */ #include #include #include #include #include #include /* ************************************************************************** */ /* 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; }