Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_rot.c Source File

pal_rot.c

00001 /*******************************************************************************
00002  * Copyright 2016-2018 ARM Ltd.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  *******************************************************************************/
00016 
00017 
00018 #include "pal.h"
00019 #include "pal_plat_rot.h"
00020 #include "sotp.h"
00021 #define TRACE_GROUP "PAL"
00022 
00023 /*
00024  * Here we define const keys for RoT derivation algorithm.
00025  * Must be 16 characters or less
00026  */
00027 #define PAL_STORAGE_SIGNATURE_128_BIT_KEY  "RoTStorageSgn128"
00028 #define PAL_STORAGE_ENCRYPTION_128_BIT_KEY "RoTStorageEnc128"
00029 #define PAL_STORAGE_ENCRYPTION_256_BIT_KEY "StorageEnc256HMACSHA256SIGNATURE"
00030 
00031 
00032 palStatus_t pal_osGetDeviceKey(palDevKeyType_t keyType, uint8_t *key, size_t keyLenBytes)
00033 {
00034     palStatus_t status = PAL_SUCCESS;
00035     sotp_result_e sotpStatus;
00036     uint8_t rotBuffer[PAL_DEVICE_KEY_SIZE_IN_BYTES] __attribute__ ((aligned(4))) = {0};
00037 
00038     PAL_VALIDATE_CONDITION_WITH_ERROR(((keyLenBytes < PAL_DEVICE_KEY_SIZE_IN_BYTES) || ((palOsStorageHmacSha256  == keyType) && (keyLenBytes < PAL_SHA256_DEVICE_KEY_SIZE_IN_BYTES))), PAL_ERR_BUFFER_TOO_SMALL )
00039     PAL_VALIDATE_CONDITION_WITH_ERROR((NULL == key), PAL_ERR_NULL_POINTER )
00040 
00041     status = pal_plat_osGetRoT(rotBuffer, keyLenBytes);
00042 
00043 #if (PAL_USE_HW_ROT == 0)
00044 
00045     //If Rot not exists,try to generate random buffer and set as RoT
00046     if (status == PAL_ERR_ITEM_NOT_EXIST ) {
00047         status = pal_osRandomBuffer(rotBuffer, PAL_DEVICE_KEY_SIZE_IN_BYTES);
00048         if (PAL_SUCCESS == status)
00049         {
00050             sotpStatus = sotp_set(SOTP_TYPE_ROT, PAL_DEVICE_KEY_SIZE_IN_BYTES, (uint32_t *)rotBuffer);
00051             if (SOTP_SUCCESS != sotpStatus) {
00052                 status = PAL_ERR_GENERIC_FAILURE ;
00053             }
00054         }
00055     }
00056 #endif
00057 
00058     if (PAL_SUCCESS == status)
00059     {   // Logic of RoT according to key type using 128 bit strong Key Derivation Algorithm
00060 
00061 #if (PAL_DEVICE_KEY_DERIVATION_BACKWARD_COMPATIBILITY_CALC == 1) //calculate the key derivation in an old way
00062         switch(keyType)
00063         {
00064             case palOsStorageEncryptionKey128Bit:
00065             {
00066                 //USE strong KDF here!
00067                 status = pal_cipherCMAC((const unsigned char*)PAL_STORAGE_ENCRYPTION_128_BIT_KEY, PAL_DEVICE_KEY_SIZE_IN_BITS, (const unsigned char *)rotBuffer, PAL_DEVICE_KEY_SIZE_IN_BYTES, key);
00068                 break;
00069             }
00070             case palOsStorageSignatureKey128Bit :
00071             {
00072                 //USE strong KDF here!
00073                 status = pal_cipherCMAC((const unsigned char *)PAL_STORAGE_SIGNATURE_128_BIT_KEY, PAL_DEVICE_KEY_SIZE_IN_BITS, (const unsigned char *)rotBuffer, PAL_DEVICE_KEY_SIZE_IN_BYTES, key);
00074                 break;
00075             }
00076             case palOsStorageHmacSha256 :
00077             {
00078                 size_t outputLenInBytes = 0;
00079                 status = pal_mdHmacSha256((const unsigned char *)PAL_STORAGE_ENCRYPTION_256_BIT_KEY, PAL_SHA256_DEVICE_KEY_SIZE_IN_BYTES, (const unsigned char*)rotBuffer, PAL_DEVICE_KEY_SIZE_IN_BYTES, key, &outputLenInBytes);
00080                 break;
00081             }
00082             default:
00083                 status = PAL_ERR_INVALID_ARGUMENT ;
00084         } //switch end
00085 #else //calculate the key derivation in a new way
00086         switch(keyType)
00087         {
00088             case palOsStorageEncryptionKey128Bit:
00089             {
00090                 //USE strong KDF here!
00091                 status = pal_cipherCMAC((const unsigned char*)rotBuffer, PAL_DEVICE_KEY_SIZE_IN_BITS, (const unsigned char *)PAL_STORAGE_ENCRYPTION_128_BIT_KEY, PAL_DEVICE_KEY_SIZE_IN_BYTES, key);
00092                 break;
00093             }
00094             case palOsStorageSignatureKey128Bit :
00095             {
00096                 //USE strong KDF here!
00097                 status = pal_cipherCMAC((const unsigned char*)rotBuffer, PAL_DEVICE_KEY_SIZE_IN_BITS, (const unsigned char *)PAL_STORAGE_SIGNATURE_128_BIT_KEY, PAL_DEVICE_KEY_SIZE_IN_BYTES, key);
00098                 break;
00099             }
00100             case palOsStorageHmacSha256 :
00101             {
00102                 size_t outputLenInBytes = 0;
00103                 status = pal_mdHmacSha256((const unsigned char*)rotBuffer, PAL_DEVICE_KEY_SIZE_IN_BYTES, (const unsigned char *)PAL_STORAGE_ENCRYPTION_256_BIT_KEY, PAL_SHA256_DEVICE_KEY_SIZE_IN_BYTES, key, &outputLenInBytes);
00104                 break;
00105             }
00106             default:
00107                 status = PAL_ERR_INVALID_ARGUMENT ;
00108         } //switch end
00109 #endif
00110 
00111     } // outer if
00112     else
00113     {
00114         status = PAL_ERR_GET_DEV_KEY ;
00115     }
00116 
00117     return status;
00118 
00119 }
00120 
00121 
00122 palStatus_t pal_osSetRoT(uint8_t *key, size_t keyLenBytes) {
00123 
00124     palStatus_t status = PAL_SUCCESS;
00125 
00126     PAL_VALIDATE_CONDITION_WITH_ERROR(((keyLenBytes != PAL_DEVICE_KEY_SIZE_IN_BYTES)), PAL_ERR_INVALID_ARGUMENT )
00127     PAL_VALIDATE_CONDITION_WITH_ERROR((NULL == key), PAL_ERR_NULL_POINTER )
00128 
00129 #if (PAL_USE_HW_ROT == 0)
00130         status = pal_plat_osSetRoT(key, keyLenBytes);
00131 #else
00132         return PAL_ERR_NOT_IMPLEMENTED;
00133 #endif
00134     return status;
00135 }