Jetson Linux API Reference

32.6.1 Release

 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
key_mgnt.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020-2021, NVIDIA Corporation. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10 
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13 
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
31 #include <common.h>
32 #include <ekb_helper.h>
33 #include <err.h>
34 #include <fuse.h>
35 #include <openssl/cmac.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <tegra_se.h>
40 #include <tegra_se_internal.h>
41 #include <trusty_std.h>
42 #include <tegra_se.h>
43 
58 /*
59  * Random fixed vector for EKB.
60  *
61  * Note: This vector MUST match the 'fv' vector used for EKB binary
62  * generation process.
63  * ba d6 6e b4 48 49 83 68 4b 99 2f e5 4a 64 8b b8
64  */
65 static uint8_t fv_for_ekb[] = {
66  0xba, 0xd6, 0x6e, 0xb4, 0x48, 0x49, 0x83, 0x68,
67  0x4b, 0x99, 0x2f, 0xe5, 0x4a, 0x64, 0x8b, 0xb8,
68 };
69 
70 /*
71  * Random fixed vector used to derive SSK_DK (Derived Key).
72  *
73  * e4 20 f5 8d 1d ea b5 24 c2 70 d8 d2 3e ca 45 e8
74  */
75 static uint8_t fv_for_ssk_dk[] = {
76  0xe4, 0x20, 0xf5, 0x8d, 0x1d, 0xea, 0xb5, 0x24,
77  0xc2, 0x70, 0xd8, 0xd2, 0x3e, 0xca, 0x45, 0xe8,
78 };
79 
80 /*
81  * Root keys derived from SE keyslots.
82  */
83 static uint8_t kek2_rk_for_ekb[AES_KEY_128_SIZE] = { 0 };
84 static uint8_t ssk_rk[AES_KEY_128_SIZE] = { 0 };
85 static uint8_t demo_256_rk[AES_KEY_256_SIZE] = { 0 };
86 
87 /*
88  * Derived keys from NIST-SP-800-108.
89  */
90 static uint8_t ekb_ek[AES_KEY_128_SIZE] = { 0 };
91 static uint8_t ekb_ak[AES_KEY_128_SIZE] = { 0 };
92 static uint8_t ssk_dk[AES_KEY_128_SIZE] = { 0 };
93 
116 static int nist_sp_800_108_with_cmac(uint8_t *key,
117  uint32_t key_len,
118  char const *context,
119  char const *label,
120  uint32_t dk_len,
121  uint8_t *out_dk)
122 {
123  uint8_t *message = NULL, *mptr;
124  uint8_t counter[] = { 1 }, zero_byte[] = { 0 };
125  uint32_t L[] = { __builtin_bswap32(dk_len * 8) };
126  int msg_len;
127  int rc = NO_ERROR;
128  CMAC_CTX *cmac = NULL;
129  size_t cmact_len;
130  int i, n;
131 
132  if ((key_len != AES_KEY_128_SIZE) && (key_len != AES_KEY_256_SIZE))
133  return ERR_INVALID_ARGS;
134 
135  if ((dk_len % AES_BLOCK_SIZE) != 0)
136  return ERR_INVALID_ARGS;
137 
138  if (!key || !context || !label || !out_dk)
139  return ERR_INVALID_ARGS;
140 
141  /*
142  * Regarding to NIST-SP-800-108
143  * message = counter || label || 0 || context || L
144  *
145  * A || B = The concatenation of binary strings A and B.
146  */
147  msg_len = strlen(context) + strlen(label) + 2 + sizeof(L);
148  message = malloc(msg_len);
149  if (message == NULL) {
150  TLOGE("%s: malloc failed.\n", __func__);
151  return ERR_NO_MEMORY;
152  }
153 
154  /* AES-CMAC */
155  cmac = CMAC_CTX_new();
156  if (cmac == NULL) {
157  TLOGE("%s: CMAC_CTX_new failed.\n", __func__);
158  rc = ERR_NO_MEMORY;
159  goto kdf_error;
160  }
161 
162  /* Concatenate the messages */
163  mptr = message;
164  memcpy(mptr , counter, sizeof(counter));
165  mptr++;
166  memcpy(mptr, label, strlen(label));
167  mptr += strlen(label);
168  memcpy(mptr, zero_byte, sizeof(zero_byte));
169  mptr++;
170  memcpy(mptr, context, strlen(context));
171  mptr += strlen(context);
172  memcpy(mptr, L, sizeof(L));
173 
174  /* n: iterations of the PRF count */
175  n = dk_len / AES_BLOCK_SIZE;
176 
177  for (i = 0; i < n; i++) {
178  /* Update the counter */
179  message[0] = i + 1;
180 
181  /* re-init initial vector for each iteration */
182  if (key_len == AES_KEY_128_SIZE)
183  CMAC_Init(cmac, key, AES_KEY_128_SIZE, EVP_aes_128_cbc(), NULL);
184  else
185  CMAC_Init(cmac, key, AES_KEY_256_SIZE, EVP_aes_256_cbc(), NULL);
186 
187  CMAC_Update(cmac, message, msg_len);
188  CMAC_Final(cmac, (out_dk + (i * AES_BLOCK_SIZE)), &cmact_len);
189  }
190 
191  CMAC_CTX_free(cmac);
192 
193 kdf_error:
194  free(message);
195  return rc;
196 }
197 
199 {
200  int rc = NO_ERROR;
201 
202  /*
203  * Derive root keys by performing AES-ECB encryption with the fixed
204  * vector (fv) and the key in the KEK2 and SSK SE keyslot.
205  */
207  fv_for_ekb, sizeof(fv_for_ekb),
208  SE_AES_KEYSLOT_KEK2_128B);
209  if (rc != NO_ERROR) {
210  TLOGE("%s: failed to derive KEK2 root key (%d)\n", __func__, rc);
211  goto root_key_fail;
212  }
213 
214  rc = se_derive_root_key(ssk_rk, sizeof(ssk_rk),
215  fv_for_ssk_dk, sizeof(fv_for_ssk_dk),
216  SE_AES_KEYSLOT_SSK);
217  if (rc != NO_ERROR) {
218  TLOGE("%s: failed to derive SSK root key (%d)\n", __func__, rc);
219  goto root_key_fail;
220  }
221 
222  /*
223  * Derive 256-bit root key from KEK256 SE keyslot.
224  *
225  * To support this, you need to modify the BR BCT file
226  * e.g. "tegra194-br-bct-sdmmc.cfg" (or "tegra194-br-bct-qspi.cfg").
227  * Add "BctKEKKeySelect = 1" into the BR BCT file.
228  * The BootRom will check the BCT to load KEK0 and KEK1 as a single
229  * 256-bit fuse into KEK256 SE keyslot.
230  */
231  rc = se_nist_sp_800_108_with_cmac(SE_AES_KEYSLOT_KEK256, AES_KEY_256_SIZE,
232  "Derived 256-bit root key", "256-bit key",
233  AES_KEY_256_SIZE, demo_256_rk);
234  if (rc != NO_ERROR)
235  TLOGE("%s: failed to derive 256-bit root key (%d)\n", __func__, rc);
236 
237 root_key_fail:
238  /* Clear keys from SE keyslots */
239  rc = se_clear_aes_keyslots();
240  if (rc != NO_ERROR)
241  TLOGE("%s: failed to clear SE keyslots (%d)\n", __func__, rc);
242 
243  return rc;
244 }
245 
246 static int set_ekb_key_to_keyslot(uint32_t keyslot, uint8_t key_index)
247 {
248  uint8_t *key_in_ekb;
249 
250  key_in_ekb = ekb_get_key(key_index);
251  if (key_in_ekb == NULL) {
252  return ERR_NOT_VALID;
253  }
254 
255  TLOGE("Setting EKB key %d to slot %d\n", key_index, keyslot);
256  return se_write_keyslot(key_in_ekb, AES_KEY_128_SIZE, AES_QUAD_KEYS, keyslot);
257 }
258 
259 static int tegra_se_cmac_self_test(void)
260 {
261  se_cmac_ctx *se_cmac = NULL;
262  uint8_t test_key_256[] = {
263  0x72, 0xd1, 0x1f, 0x8b, 0x1c, 0x01, 0xe1, 0x5c,
264  0x49, 0x86, 0x07, 0x2a, 0xe5, 0x63, 0x42, 0x21,
265  0x65, 0x3f, 0x2e, 0x7f, 0x22, 0xfd, 0x05, 0x4c,
266  0x60, 0xc9, 0x76, 0xa6, 0xf4, 0x3a, 0x93, 0xfe,
267  };
268  char test_msg[] = "SE_aes_cmac_test_string";
269  uint8_t openssl_cmac_digest[AES_BLOCK_SIZE] = { 0 };
270  uint8_t se_cmac_digest[AES_BLOCK_SIZE] = {0};
271  size_t cmac_len;
272 
273  /* OpenSSL AES-CMAC */
274  CMAC_CTX *cmac = NULL;
275 
276  cmac = CMAC_CTX_new();
277  if (cmac == NULL)
278  return ERR_NO_MEMORY;
279  CMAC_Init(cmac, test_key_256, AES_KEY_256_SIZE, EVP_aes_256_cbc(), NULL);
280 
281  CMAC_Update(cmac, test_msg, sizeof(test_msg));
282  CMAC_Final(cmac, openssl_cmac_digest, &cmac_len);
283  CMAC_CTX_free(cmac);
284 
285  /* Write key into keyslot */
286  se_write_keyslot(test_key_256, AES_KEY_256_SIZE, AES_QUAD_KEYS_256, SE_AES_KEYSLOT_KEK256);
287 
288  /* SE AES-CMAC */
289  se_cmac = tegra_se_cmac_new();
290  if (se_cmac == NULL)
291  return ERR_NO_MEMORY;
292 
293  tegra_se_cmac_init(se_cmac, SE_AES_KEYSLOT_KEK256, AES_KEY_256_SIZE);
294  tegra_se_cmac_update(se_cmac, test_msg, sizeof(test_msg));
295  tegra_se_cmac_final(se_cmac, se_cmac_digest, &cmac_len);
296 
297  tegra_se_cmac_free(se_cmac);
298 
299  /* Verify the result */
300  if (memcmp(openssl_cmac_digest, se_cmac_digest, cmac_len)) {
301  TLOGE("%s: Tegra SE AES-CMAC verification is not match.\n", __func__);
302  return ERR_GENERIC;
303  }
304 
305  return NO_ERROR;
306 }
307 
309 {
310  uint8_t test_key_256[] = {
311  0xc0, 0x3c, 0x15, 0x4e, 0xe5, 0x6c, 0xb5, 0x69,
312  0x1b, 0x27, 0xd9, 0x2e, 0x7f, 0x34, 0xfb, 0x8a,
313  0x88, 0x6c, 0x0c, 0x40, 0xf9, 0x51, 0x66, 0xe0,
314  0x1d, 0x43, 0x5b, 0xba, 0xa3, 0x90, 0x47, 0x32,
315  };
316  const char context_str[] = "nist sp 800-108 KDF verification";
317  const char label_str[] = "KDF comparison";
318  uint8_t sw_derived_key[AES_KEY_256_SIZE] = { 0 };
319  uint8_t hw_derived_key[AES_KEY_256_SIZE] = { 0 };
320 
321  /* SW-based NIST SP 800-108 KDF */
322  nist_sp_800_108_with_cmac(test_key_256, AES_KEY_256_SIZE,
323  context_str, label_str,
324  AES_KEY_256_SIZE, sw_derived_key);
325 
326  /* Write key into keyslot */
327  se_write_keyslot(test_key_256, AES_KEY_256_SIZE, AES_QUAD_KEYS_256, SE_AES_KEYSLOT_KEK256);
328 
329  /* HW-based NIST SP 800-108 KDF */
330  se_nist_sp_800_108_with_cmac(SE_AES_KEYSLOT_KEK256, AES_KEY_256_SIZE,
331  context_str, label_str,
332  AES_KEY_256_SIZE, hw_derived_key);
333 
334  /* Verify the result */
335  if (memcmp(sw_derived_key, hw_derived_key, AES_KEY_256_SIZE)) {
336  TLOGE("%s: Tegra SE NIST 800-108 KDF verification is not match.\n", __func__);
337  return ERR_GENERIC;
338  }
339 
340  return NO_ERROR;
341 }
342 
344 {
345  int rc = NO_ERROR;
346 
347  TLOGE("%s .......\n", __func__);
348 
349  /* Query ECID */
350  fuse_query_ecid();
351 
352  /* Derive root keys from SE keyslots. */
354  if (rc != NO_ERROR)
355  goto err_key_mgnt;
356 
357  /* Derive EKB_EK */
358  rc = nist_sp_800_108_with_cmac(kek2_rk_for_ekb, AES_KEY_128_SIZE,
359  "ekb", "encryption",
360  AES_KEY_128_SIZE, ekb_ek);
361  if (rc != NO_ERROR)
362  goto err_key_mgnt;
363 
364  /* Derive EKB_AK */
365  rc = nist_sp_800_108_with_cmac(kek2_rk_for_ekb, AES_KEY_128_SIZE,
366  "ekb", "authentication",
367  AES_KEY_128_SIZE, ekb_ak);
368  if (rc != NO_ERROR)
369  goto err_key_mgnt;
370 
371  /*
372  * Derive SSK_DK
373  *
374  * This demos how to derive a key from SE keyslot. So developers
375  * can follow the same scenario to derive keys for different
376  * security purposes.
377  */
378  rc = nist_sp_800_108_with_cmac(ssk_rk, AES_KEY_128_SIZE,
379  "ssk", "derivedkey",
380  AES_KEY_128_SIZE, ssk_dk);
381  if (rc != NO_ERROR)
382  goto err_key_mgnt;
383 
384  /* Verify EKB */
385  rc = ekb_verification(ekb_ak, ekb_ek);
386  if (rc != NO_ERROR)
387  goto err_key_mgnt;
388 
389  /* Set ekb key to SBK key slot to support for cboot crypto operation */
390  rc = set_ekb_key_to_keyslot(SE_AES_KEYSLOT_SBK, EKB_USER_KEY_KERNEL_ENCRYPTION);
391 
392  /* Tegra Security Engine AES-CMAC self test */
394  return ERR_GENERIC;
395  /* Tegra Security Engine NIST 800-108 KDF self test */
397  return ERR_GENERIC;
398 err_key_mgnt:
399  if (rc != NO_ERROR)
400  TLOGE("%s: failed (%d)\n", __func__, rc);
401  return rc;
402 }
403 
static uint8_t demo_256_rk[AES_KEY_256_SIZE]
Definition: key_mgnt.c:85
static uint8_t kek2_rk_for_ekb[AES_KEY_128_SIZE]
Definition: key_mgnt.c:83
static int set_ekb_key_to_keyslot(uint32_t keyslot, uint8_t key_index)
Definition: key_mgnt.c:246
static uint8_t fv_for_ekb[]
Definition: key_mgnt.c:65
static int tegra_se_nist_800_108_kdf_self_test(void)
Definition: key_mgnt.c:308
int tegra_se_cmac_init(se_cmac_ctx *se_cmac, se_aes_keyslot_t keyslot, uint32_t keylen)
Initialize the SE CMAC from a user-provided key.
int se_write_keyslot(uint8_t *key_in, uint32_t keylen, uint32_t key_quad_sel, uint32_t keyslot)
int se_nist_sp_800_108_with_cmac(se_aes_keyslot_t keyslot, uint32_t key_len, char const *context, char const *label, uint32_t dk_len, uint8_t *out_dk)
A hardware-based NIST-SP-800-108 KDF; derives keys from the SE keyslot.
AES-256 hardware key definition functions
int tegra_se_cmac_update(se_cmac_ctx *se_cmac, void *data, uint32_t dlen)
Caches input data in an SE CMAC.
se_cmac_ctx * tegra_se_cmac_new(void)
Creates an SE CMAC context.
static int key_mgnt_derive_root_keys(void)
Definition: key_mgnt.c:198
void tegra_se_cmac_free(se_cmac_ctx *se_cmac)
Frees an SE CMAC context.
static uint8_t ssk_dk[AES_KEY_128_SIZE]
Definition: key_mgnt.c:92
static int nist_sp_800_108_with_cmac(uint8_t *key, uint32_t key_len, char const *context, char const *label, uint32_t dk_len, uint8_t *out_dk)
A software-based NIST-SP-800-108 KDF; derives keys from a key in a key buffer.
Definition: key_mgnt.c:116
static uint8_t ekb_ek[AES_KEY_128_SIZE]
Definition: key_mgnt.c:90
int key_mgnt_processing(void)
Definition: key_mgnt.c:343
static uint8_t ekb_ak[AES_KEY_128_SIZE]
Definition: key_mgnt.c:91
static uint8_t ssk_rk[AES_KEY_128_SIZE]
Definition: key_mgnt.c:84
uint32_t se_clear_aes_keyslots(void)
static uint8_t fv_for_ssk_dk[]
Definition: key_mgnt.c:75
struct tegra_se_cmac_context se_cmac_ctx
Definition: tegra_se.h:199
uint32_t se_derive_root_key(uint8_t *root_key, size_t root_key_len, uint8_t *fv, size_t fv_len, uint32_t keyslot)
static int tegra_se_cmac_self_test(void)
Definition: key_mgnt.c:259
int tegra_se_cmac_final(se_cmac_ctx *se_cmac, uint8_t *out, uint32_t *poutlen)
Finalizes a SE CMAC.