Skip to content

Commit 5c11b63

Browse files
committed
Add hardware signing and key exporting
1 parent eeb7c01 commit 5c11b63

File tree

2 files changed

+192
-112
lines changed

2 files changed

+192
-112
lines changed

main.c

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
/*
2+
* Copyright (c) 2019, Arm Limited and affiliates
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include <stdio.h>
19+
#include <inttypes.h>
20+
#include <string.h>
21+
22+
#if defined(ATCA_HAL_I2C)
23+
#include "psa/crypto.h"
24+
#include "atecc608a_se.h"
25+
#include "atca_status.h"
26+
#include "atca_devtypes.h"
27+
#include "atca_iface.h"
28+
#include "atca_command.h"
29+
#include "atca_basic.h"
30+
#include "atca_helpers.h"
31+
32+
#define ASSERT_STATUS(actual, expected) \
33+
do \
34+
{ \
35+
int ASSERT_STATUS_actual = (actual); \
36+
int ASSERT_STATUS_expected = (expected); \
37+
if ((ASSERT_STATUS_actual) != (ASSERT_STATUS_expected)) \
38+
{ \
39+
printf("assertion failed at %s:%d " \
40+
"(actual=%d expected=%d)\n", __FILE__, __LINE__, \
41+
ASSERT_STATUS_actual, ASSERT_STATUS_expected); \
42+
return -1; \
43+
} \
44+
} while(0)
45+
46+
extern ATCAIfaceCfg atca_iface_config;
47+
static const uint8_t hash_input1[] = "abc";
48+
/* SHA-256 hash of ['a','b','c'] */
49+
static const uint8_t sha256_expected_hash1[] = {
50+
0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
51+
0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD
52+
};
53+
54+
static const uint8_t hash_input2[] = "";
55+
/* SHA-256 hash of an empty string */
56+
static const uint8_t sha256_expected_hash2[] = {
57+
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
58+
0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
59+
};
60+
61+
62+
psa_status_t atecc608a_hash_sha256(const uint8_t *input, size_t input_size,
63+
const uint8_t *expected_hash, size_t expected_hash_size)
64+
{
65+
uint8_t actual_hash[ATCA_SHA_DIGEST_SIZE] = {0};
66+
67+
printf("SHA-256:\n\n");
68+
atcab_printbin_label("Input: ", (uint8_t *)input, input_size);
69+
atcab_printbin_label("Expected Hash: ", (uint8_t *)expected_hash, expected_hash_size);
70+
ASSERT_STATUS(atcab_init(&atca_iface_config), ATCA_SUCCESS);
71+
ASSERT_STATUS(atcab_hw_sha2_256(input, input_size, actual_hash), ATCA_SUCCESS);
72+
ASSERT_STATUS(atcab_release(), ATCA_SUCCESS);
73+
atcab_printbin_label("Actual Hash: ", actual_hash, ATCA_SHA_DIGEST_SIZE);
74+
ASSERT_STATUS(memcmp(actual_hash, expected_hash, sizeof(actual_hash)), 0);
75+
printf("Success!\n\n");
76+
77+
return 0;
78+
}
79+
80+
psa_status_t atecc608a_print_locked_zones()
81+
{
82+
bool locked;
83+
printf("--- Device locks information ---\n");
84+
ASSERT_STATUS(atcab_init(&atca_iface_config), ATCA_SUCCESS);
85+
ASSERT_STATUS(atcab_is_locked(LOCK_ZONE_CONFIG, &locked), ATCA_SUCCESS);
86+
printf(" - Config locked: %d\n", locked);
87+
ASSERT_STATUS(atcab_is_locked(LOCK_ZONE_DATA, &locked), ATCA_SUCCESS);
88+
printf(" - Data locked: %d\n", locked);
89+
for(uint8_t i=0; i < 16; i++)
90+
{
91+
ASSERT_STATUS(atcab_is_slot_locked(i, &locked), ATCA_SUCCESS);
92+
printf(" - Slot %d locked: %d\n", i, locked);
93+
}
94+
ASSERT_STATUS(atcab_release(), ATCA_SUCCESS);
95+
printf("--------------------------------\n");
96+
return PSA_SUCCESS;
97+
}
98+
99+
psa_status_t atecc608a_print_serial_number()
100+
{
101+
uint8_t serial[ATCA_SERIAL_NUM_SIZE];
102+
103+
if(atecc608a_get_serial_number(serial, ATCA_SERIAL_NUM_SIZE) != PSA_SUCCESS)
104+
{
105+
return PSA_ERROR_HARDWARE_FAILURE;
106+
}
107+
printf("Serial Number:\n");
108+
atcab_printbin_sp(serial, ATCA_SERIAL_NUM_SIZE);
109+
printf("\n");
110+
return PSA_SUCCESS;
111+
}
112+
113+
int main(void)
114+
{
115+
enum {
116+
key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1),
117+
keypair_type = PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1),
118+
key_bits = 256,
119+
hash_alg = PSA_ALG_SHA_256,
120+
alg = PSA_ALG_ECDSA(hash_alg),
121+
sig_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE(key_type, key_bits, alg),
122+
pubkey_size = PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits),
123+
hash_size = PSA_HASH_SIZE(hash_alg),
124+
};
125+
psa_status_t status;
126+
psa_key_handle_t verify_handle;
127+
uint8_t signature[sig_size];
128+
size_t signature_length = 0;
129+
const uint8_t hash[hash_size] = {
130+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
134+
};
135+
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
136+
static uint8_t pubkey[pubkey_size];
137+
size_t pubkey_len = 0;
138+
psa_key_slot_number_t atecc608a_key_slot_device = 0;
139+
140+
atecc608a_print_serial_number();
141+
142+
atecc608a_hash_sha256(hash_input1, sizeof(hash_input1) - 1,
143+
sha256_expected_hash1, sizeof(sha256_expected_hash1));
144+
145+
atecc608a_hash_sha256(hash_input2, sizeof(hash_input2) - 1,
146+
sha256_expected_hash2, sizeof(sha256_expected_hash2));
147+
148+
status = psa_crypto_init();
149+
ASSERT_STATUS(status, PSA_SUCCESS);
150+
151+
atecc608a_print_locked_zones();
152+
/* Verify that the device has a locked config before doing anything */
153+
ASSERT_STATUS(atecc608a_check_config_locked(), PSA_SUCCESS);
154+
155+
status = atecc608a_export_public_key(atecc608a_key_slot_device, pubkey,
156+
sizeof(pubkey), &pubkey_len);
157+
ASSERT_STATUS(status, PSA_SUCCESS);
158+
159+
status = atecc608a_asymmetric_sign(atecc608a_key_slot_device, alg, hash,
160+
sizeof(hash), signature,
161+
sizeof(signature), &signature_length);
162+
ASSERT_STATUS(status, PSA_SUCCESS);
163+
164+
/*
165+
* Import the secure element's public key into a volatile key slot.
166+
*/
167+
status = psa_allocate_key(&verify_handle);
168+
ASSERT_STATUS(status, PSA_SUCCESS);
169+
170+
psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_VERIFY, alg);
171+
status = psa_set_key_policy(verify_handle, &policy);
172+
ASSERT_STATUS(status, PSA_SUCCESS);
173+
174+
status = psa_import_key(verify_handle, key_type, pubkey, pubkey_len);
175+
ASSERT_STATUS(status, PSA_SUCCESS);
176+
177+
/* Verify that the signature produced by the secure element is valid. */
178+
status = psa_asymmetric_verify(verify_handle, alg, hash, sizeof(hash),
179+
signature, signature_length);
180+
ASSERT_STATUS(status, PSA_SUCCESS);
181+
182+
printf("Verification successful!\n");
183+
return 0;
184+
}
185+
#else
186+
int main(void)
187+
{
188+
printf("Not all of the required options are defined:\n"
189+
" - ATCA_HAL_I2C\n");
190+
return 0;
191+
}
192+
#endif

main.cpp

Lines changed: 0 additions & 112 deletions
This file was deleted.

0 commit comments

Comments
 (0)