blob: 6e567027c0564347159280cd100917e0a8ecef8b [file] [log] [blame]
Breno Lima30e39ac2021-03-25 17:30:02 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2016 Freescale Semiconductor, Inc.
4 * Copyright 2017 NXP
5 *
6 * These commands enable the use of the CAAM MPPubK-generation and MPSign
7 * functions in supported i.MX devices.
8 */
9
10#include <asm/byteorder.h>
11#include <asm/arch/clock.h>
12#include <linux/compiler.h>
13#include <command.h>
14#include <common.h>
15#include <environment.h>
16#include <fsl_sec.h>
17#include <mapmem.h>
18#include <memalign.h>
19
20DECLARE_GLOBAL_DATA_PTR;
21
22/**
23 * do_mfgprot() - Handle the "mfgprot" command-line command
24 * @cmdtp: Command data struct pointer
25 * @flag: Command flag
26 * @argc: Command-line argument count
27 * @argv: Array of command-line arguments
28 *
29 * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
30 * on error.
31 */
32static int do_mfgprot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
33{
34 u8 *m_ptr, *dgst_ptr, *c_ptr, *d_ptr, *dst_ptr;
35 char *pubk, *sign, *sel;
36 int m_size, i, ret;
37 u32 m_addr;
38
39 pubk = "pubk";
40 sign = "sign";
41 sel = argv[1];
42
43 /* Enable HAB clock */
44 u32 jr_size = 4;
Breno Lima8c497e12021-03-25 17:30:03 +080045 u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR +
46 FSL_CAAM_ORSR_JRa_OFFSET);
Breno Lima30e39ac2021-03-25 17:30:02 +080047
48 if (out_jr_size != jr_size) {
49 hab_caam_clock_enable(1);
50 sec_init();
51 }
52
53 if (strcmp(sel, pubk) == 0) {
54 dst_ptr = malloc_cache_aligned(FSL_CAAM_MP_PUBK_BYTES);
55 if (!dst_ptr)
56 return -ENOMEM;
57
58 ret = gen_mppubk(dst_ptr);
59 if (ret) {
60 free(dst_ptr);
61 return ret;
62 }
63
64 /* Output results */
65 puts("Public key:\n");
66 for (i = 0; i < FSL_CAAM_MP_PUBK_BYTES; i++)
67 printf("%02X", (dst_ptr)[i]);
68 puts("\n");
69 free(dst_ptr);
70
71 } else if (strcmp(sel, sign) == 0) {
72 if (argc != 4)
73 return CMD_RET_USAGE;
74
75 m_addr = simple_strtoul(argv[2], NULL, 16);
76 m_size = simple_strtoul(argv[3], NULL, 10);
77 m_ptr = map_physmem(m_addr, m_size, MAP_NOCACHE);
78 if (!m_ptr)
79 return -ENOMEM;
80
81 dgst_ptr = malloc_cache_aligned(FSL_CAAM_MP_MES_DGST_BYTES);
82 if (!dgst_ptr) {
83 ret = -ENOMEM;
84 goto free_m;
85 }
86
87 c_ptr = malloc_cache_aligned(FSL_CAAM_MP_PRVK_BYTES);
88 if (!c_ptr) {
89 ret = -ENOMEM;
90 goto free_dgst;
91 }
92
93 d_ptr = malloc_cache_aligned(FSL_CAAM_MP_PRVK_BYTES);
94 if (!d_ptr) {
95 ret = -ENOMEM;
96 goto free_c;
97 }
98
99 ret = sign_mppubk(m_ptr, m_size, dgst_ptr, c_ptr, d_ptr);
100 if (ret)
101 goto free_d;
102
103 /* Output results */
104 puts("Message: ");
105 for (i = 0; i < m_size; i++)
106 printf("%02X ", (m_ptr)[i]);
107 puts("\n");
108
109 puts("Message Representative Digest(SHA-256):\n");
110 for (i = 0; i < FSL_CAAM_MP_MES_DGST_BYTES; i++)
111 printf("%02X", (dgst_ptr)[i]);
112 puts("\n");
113
114 puts("Signature:\n");
115 puts("C:\n");
116 for (i = 0; i < FSL_CAAM_MP_PRVK_BYTES; i++)
117 printf("%02X", (c_ptr)[i]);
118 puts("\n");
119
120 puts("d:\n");
121 for (i = 0; i < FSL_CAAM_MP_PRVK_BYTES; i++)
122 printf("%02X", (d_ptr)[i]);
123 puts("\n");
124free_d:
125 free(d_ptr);
126free_c:
127 free(c_ptr);
128free_dgst:
129 free(dgst_ptr);
130free_m:
131 unmap_sysmem(m_ptr);
132
133 } else {
134 return CMD_RET_USAGE;
135 }
136 return ret;
137}
138
139/***************************************************/
140static char mfgprot_help_text[] =
141 "Usage:\n"
142 "Print the public key for Manufacturing Protection\n"
143 "\tmfgprot pubk\n"
144 "Generates a Manufacturing Protection signature\n"
145 "\tmfgprot sign <data_addr> <size>";
146
147U_BOOT_CMD(
148 mfgprot, 4, 1, do_mfgprot,
149 "Manufacturing Protection\n",
150 mfgprot_help_text
151);