Mbed OS 文档翻译 之 参考(API(驱动(DeviceKey)))

DeviceKey

DeviceKey 是一种从信任密钥的根实现密钥派生的机制。DeviceKey 机制生成安全功能所需的对称密钥。您可以使用这些密钥进行加密,身份验证等。DeviceKey API 允许密钥派生而不暴露实际的信任根,以减少在设备外意外暴露信任根的可能性。

我们已经根据 NIST SP 800-108,“计数器模式下的 KDF” 部分实现了 DeviceKey,其中 AES-CMAC 作为伪随机函数。

信任的根源

DeviceKey 用于派生其他密钥的信任密钥的根是使用硬件随机生成器(如果存在)或使用在生产过程中注入设备的密钥生成的。

这个信任根所要求的特征是:

  • 每个设备必须是唯一的。
  • 一定很难猜到。
  • 它必须至少为 128 位。
  • 它必须保密。

DeviceKey 功能使用 NVStore 组件将信任密钥的根保留在内部存储中。内部存储可防止对设备的外部物理攻击。

如果设备中有真正的随机数生成器,则首次使用 DeviceKey 时会生成信任根。如果没有可用的真随机数生成器,则必须在调用密钥派生 API 之前将注入的信任密钥根传递给 DeviceKey。

密钥派生 API

generate_derived_key:此 API 根据数据数组生成一个新密钥(调用者提供的盐。单个 salt 值始终生成相同的密钥,因此如果需要新密钥,则必须使用新的 salt 值。盐可以是 有任何值 - 数组,字符串等。

生成的密钥长度可以是 128 位或 256 位。

信任注入 API 的根

device_inject_root_of_trust:如果设备不支持真正的随机数生成器(未定义 DEVICE_TRNG),则必须在设备的生命周期内调用此 API,然后才能调用密钥派生。

使用 DeviceKey

DeviceKey 是一个单例类,这意味着系统只能有一个实例。

要实例化 DeviceKey,您需要调用其 get_instance 成员函数,如下所示:

    DeviceKey &deviceKey = DeviceKey::get_instance();

测试 DeviceKey

使用 mbed 命令运行 DeviceKey 功能测试,如下所示:

    mbed test -n features-device_key-tests-device_key-functionality

DeviceKey API 类参考

mbed::DeviceKey 类参考

公共成员函数
int generate_derived_key (const unsigned char *isalt, size_t isalt_size, unsigned char *output, uint16_t ikey_type)
int device_inject_root_of_trust (uint32_t *value, size_t isize)
静态公共成员函数
static DeviceKeyget_instance ()
 作为单例,返回类的单个实例。此类为单例的原因如下:更多...

DeviceKey 示例

/*
* Copyright (c) 2018 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "mbed.h"
#include "DeviceKey.h"

//print a unsigned char buffer in hex format
void print_buffer(unsigned char *buf, size_t size)
{
    for (size_t i = 0; i < size; i++) {
        printf("%02X", buf[i]);
    }
}

//Injection of a dummy key when there is no TRNG
int inject_rot_key()
{
    uint32_t key[DEVICE_KEY_16BYTE / sizeof(uint32_t)];

    memset(key, 0, DEVICE_KEY_16BYTE);
    memcpy(key, "ABCDEF1234567890", DEVICE_KEY_16BYTE);
    int size = DEVICE_KEY_16BYTE;
    DeviceKey& devkey = DeviceKey::get_instance();
    return devkey.device_inject_root_of_trust(key, size);
}

// Entry point for the example
int main()
{
    unsigned char derive_key1 [DEVICE_KEY_32BYTE];
    unsigned char derive_key2 [DEVICE_KEY_32BYTE];
    unsigned char salt1[] = "SALT1 ----- SALT1 ------ SALT1";
    unsigned char salt2[] = "SALT2 ----- SALT2 ------ SALT2";
    int ret = DEVICEKEY_SUCCESS;

    printf("\n--- Mbed OS DeviceKey example ---\n");

    //DeviceKey is a singleton
    DeviceKey& devkey = DeviceKey::get_instance();

#if not defined(DEVICE_TRNG)

    //If TRNG is not available it is a must to inject the ROT before the first call to derive key method.
    printf("\n--- No TRNG support for this device. injecting ROT. ---\n");
    ret = inject_rot_key();
    if (DEVICEKEY_SUCCESS != ret && DEVICEKEY_ALREADY_EXIST != ret) {
        printf("\n--- Error, injection of ROT key has failed with status %d ---\n", ret);
        return -1;
    }

    if ( DEVICEKEY_ALREADY_EXIST == ret ) {
        printf("\n--- ROT Key already exists in the persistent memory. ---\n", ret);
    } else {
        printf("\n--- ROT Key injected and stored in persistent memory. ---\n", ret);
    }

#endif

    printf("\n--- Using the following salt for key derivation: %s ---\n", salt1);

    //16 byte key derivation.
    printf("--- First call to derive key, requesting derived key of 16 byte ---\n");
    ret = devkey.generate_derived_key(salt1, sizeof(salt1), derive_key1, DEVICE_KEY_16BYTE);
    if (DEVICEKEY_SUCCESS != ret) {
        printf("\n--- Error, derive key failed with error code %d ---\n", ret);
        return -1;
    }

    printf("--- Derived key1 is: \n");
    print_buffer(derive_key1, DEVICE_KEY_16BYTE);
    printf("\n");

    //16 byte key derivation with the same salt should result with the same derived key.
    printf("\n--- Second call to derive key with the same salt. ---\n");
    ret = devkey.generate_derived_key(salt1, sizeof(salt1), derive_key2, DEVICE_KEY_16BYTE);
    if (DEVICEKEY_SUCCESS != ret) {
        printf("\n--- Error, derive key failed with error code %d ---\n", ret);
        return -1;
    }

    printf("--- Derived key2 should be equal to key1 from the first call. key2 is: \n");
    print_buffer(derive_key2, DEVICE_KEY_16BYTE);
    printf("\n");

    if (memcmp(derive_key1, derive_key2, DEVICE_KEY_16BYTE) != 0) {
        printf("--- Error, first key and second key do not match ---\n");
        return -1;
    } else {
        printf("--- Keys match ---\n");
    }

    printf("\n--- Using the following salt for key derivation %s ---\n", salt2);

    //16 byte key derivation with the different salt should result with new derived key.
    ret = devkey.generate_derived_key(salt2, sizeof(salt2), derive_key1, DEVICE_KEY_16BYTE);
    if (DEVICEKEY_SUCCESS != ret) {
        printf("\n--- Error, derive key failed with error code %d ---\n", ret);
        return -1;
    }

    printf("--- Third call to derive key with the different salt should result with a new derived key1: \n");
    print_buffer(derive_key1, DEVICE_KEY_16BYTE);
    printf("\n");

    if (memcmp(derive_key1, derive_key2, DEVICE_KEY_16BYTE) == 0) {
        printf("--- Error, first key and second key do not match ---\n");
        return -1;
    } else {
        printf("--- Keys not match ---\n");
    }

    //32 byte key derivation.
    printf("\n--- 32 byte key derivation example. ---\n");
    ret = devkey.generate_derived_key(salt2, sizeof(salt2), derive_key2, DEVICE_KEY_32BYTE);
    if (DEVICEKEY_SUCCESS != ret) {
        printf("\n--- Error, derive key failed with error code %d ---\n", ret);
        return -1;
    }

    printf("--- 32 byte derived key is: \n");
    print_buffer(derive_key2, DEVICE_KEY_32BYTE);
    printf("\n");

    printf("\n--- Mbed OS DeviceKey example done. ---\n");

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值