Chip ID
Requirements
Enable quiddikey driver in your application.
Description
This example shows how to make a chip identification procedure using GAP9’s puf(quiddikey).
How to run
cmake -B build
cmake --build build --target menuconfig # Select your board in the menu
cmake --build build --target run
Or use the gap command:
gap init
gap menuconfig
gap run
cmake -B build
cmake --build build --target menuconfig # Select GVSoC in the menu
cmake --build build --target run
Or use the gap command:
gap init
gap menuconfig
gap run
Results
You should have an output looking like this (order may vary):
Chip id example
Starting enroll (first boot) procedure
Starting id verification procedure
ID verification procedure done
/*
* Copyright (C) 2023 ETH Zurich, University of Bologna and GreenWaves Technologies
* All rights reserved.
*
* This software may be modified and distributed under the terms
* of the BSD license. See the LICENSE file for details.
*
* Author: Antoine Faravelon, GWT (antoine.faravelon@greenwaves-technologies.com)
*/
#include "pmsis.h"
// NOTE1: saved AC and KC, sizes are for worst case, follow documentation to determine
// proper size for your use case
// NOTE2: In real product, this should be in eMRAM
uint8_t saved_activation_code[2048];
uint8_t saved_key_code[2048];
uint8_t saved_key[2048];
// wrap key into key_code
int wrap_key(pi_device_t *qk, uint16_t key_length, uint8_t *key, uint8_t *key_code)
{
pi_quiddikey_context_t context = {0, 0, 0, 0, 0};
// dor ok, so ok, no special context
pi_quiddikey_set_key_context(&context, uQUIDDIKEY_Started, key_length, 1, 1, 0);
return pi_quiddikey_wrap(qk, (uint32_t *)key, (uint32_t *)key_code, &context);
}
int unwrap_key(pi_device_t *qk, uint16_t key_length, uint8_t *key, uint8_t *key_code)
{
pi_quiddikey_context_t context = {0, 0, 0, 0, 0};
// dor ok, so ok, no special context
pi_quiddikey_set_key_context(&context, uQUIDDIKEY_Started, key_length, 1, 1, 0);
return pi_quiddikey_unwrap(qk, (uint32_t *)key_code, (uint32_t *)key, context.key_length);
}
void chip_id_enroll(void)
{
printf("Starting enroll (first boot) procedure\n");
int error = 0;
pi_device_t qk_device = {0};
pi_device_t *qk = &qk_device;
pi_quiddikey_conf_t conf = {0};
conf.id = 0;
conf.enroll = 1;
conf.ac = saved_activation_code;
qk_device.config = &conf;
error = pi_quiddikey_open(qk);
if(error)
{
printf("quiddikey enroll failed\n");
exit(-1);
}
pi_quiddikey_close(&qk_device);
// reopen the quiddikey in "normal" mode, failing to do so will make
// wrapped key unwrappable in normal operation mode
conf.enroll = 0;
error = pi_quiddikey_open(&qk_device);
// generate a random key
uint32_t data_length = 1024; // 1024 bits
pi_quiddikey_context_t context = {data_length, 0, 0, 0, 0};
error = pi_quiddikey_generate_random(qk, (uint32_t *)saved_key,
&context);
if(error)
{
printf("Error: could'nt generate random number\n");
exit(-1);
}
// wrap random key
error = wrap_key(qk, data_length, saved_key, saved_key_code);
if(error)
{
printf("couldn't wrap key\n");
exit(-1);
}
pi_quiddikey_close(qk);
}
void chip_id_verify(void)
{
printf("Starting id verification procedure\n");
int error = 0;
pi_device_t qk_device = {0};
pi_device_t *qk = &qk_device;
pi_quiddikey_conf_t conf = {0};
conf.id = 0;
conf.enroll = 0;
conf.ac = saved_activation_code;
qk_device.config = &conf;
error = pi_quiddikey_open(qk);
if(error)
{
printf("Failed to start quiddikey with saved AC\n");
exit(-1);
}
uint32_t key_length = 1024; // 1024 bits
uint8_t *key_check = pi_malloc(2048);
error = unwrap_key(qk, key_length, key_check, saved_key_code);
for(unsigned int i = 0; i< (key_length >> 3); i++)
{
if(key_check[i] != saved_key[i])
{
printf("Key code verifcation failed\n");
exit(-1);
}
}
pi_free(key_check);
pi_quiddikey_close(qk);
printf("ID verification procedure done\n");
}
int main(void)
{
printf("Entering chip id example\n");
// First, demonstrate enroll procedure:
// NOTE: this should only be done once at factory
chip_id_enroll();
// Now, demonstrate verification prodecure: to be done at library start
chip_id_verify();
}
# Copyright (c) 2022 GreenWaves Technologies SAS
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of GreenWaves Technologies SAS nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
cmake_minimum_required(VERSION 3.19)
###############################################################################
# Panel Control
###############################################################################
set(TARGET_NAME "chip_id")
set(TARGET_SRCS chip_id.c)
###############################################################################
# CMake pre initialization
###############################################################################
include($ENV{GAP_SDK_HOME}/utils/cmake/setup.cmake)
project(${TARGET_NAME} C ASM)
add_executable(${TARGET_NAME} ${TARGET_SRCS})
###############################################################################
# CMake post initialization
###############################################################################
setupos(${TARGET_NAME})