1 // 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
20 DECLARE_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 */
do_mfgprot(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])32 static 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 hab_caam_clock_enable(1);
45
46 u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR +
47 FSL_CAAM_ORSR_JRa_OFFSET);
48
49 if (out_jr_size != FSL_CAAM_MAX_JR_SIZE)
50 sec_init();
51
52 if (strcmp(sel, pubk) == 0) {
53 dst_ptr = malloc_cache_aligned(FSL_CAAM_MP_PUBK_BYTES);
54 if (!dst_ptr)
55 return -ENOMEM;
56
57 ret = gen_mppubk(dst_ptr);
58 if (ret) {
59 free(dst_ptr);
60 return ret;
61 }
62
63 /* Output results */
64 puts("Public key:\n");
65 for (i = 0; i < FSL_CAAM_MP_PUBK_BYTES; i++)
66 printf("%02X", (dst_ptr)[i]);
67 puts("\n");
68 free(dst_ptr);
69
70 } else if (strcmp(sel, sign) == 0) {
71 if (argc != 4)
72 return CMD_RET_USAGE;
73
74 m_addr = simple_strtoul(argv[2], NULL, 16);
75 m_size = simple_strtoul(argv[3], NULL, 10);
76 m_ptr = map_physmem(m_addr, m_size, MAP_NOCACHE);
77 if (!m_ptr)
78 return -ENOMEM;
79
80 dgst_ptr = malloc_cache_aligned(FSL_CAAM_MP_MES_DGST_BYTES);
81 if (!dgst_ptr) {
82 ret = -ENOMEM;
83 goto free_m;
84 }
85
86 c_ptr = malloc_cache_aligned(FSL_CAAM_MP_PRVK_BYTES);
87 if (!c_ptr) {
88 ret = -ENOMEM;
89 goto free_dgst;
90 }
91
92 d_ptr = malloc_cache_aligned(FSL_CAAM_MP_PRVK_BYTES);
93 if (!d_ptr) {
94 ret = -ENOMEM;
95 goto free_c;
96 }
97
98 ret = sign_mppubk(m_ptr, m_size, dgst_ptr, c_ptr, d_ptr);
99 if (ret)
100 goto free_d;
101
102 /* Output results */
103 puts("Message: ");
104 for (i = 0; i < m_size; i++)
105 printf("%02X ", (m_ptr)[i]);
106 puts("\n");
107
108 puts("Message Representative Digest(SHA-256):\n");
109 for (i = 0; i < FSL_CAAM_MP_MES_DGST_BYTES; i++)
110 printf("%02X", (dgst_ptr)[i]);
111 puts("\n");
112
113 puts("Signature:\n");
114 puts("C:\n");
115 for (i = 0; i < FSL_CAAM_MP_PRVK_BYTES; i++)
116 printf("%02X", (c_ptr)[i]);
117 puts("\n");
118
119 puts("d:\n");
120 for (i = 0; i < FSL_CAAM_MP_PRVK_BYTES; i++)
121 printf("%02X", (d_ptr)[i]);
122 puts("\n");
123 free_d:
124 free(d_ptr);
125 free_c:
126 free(c_ptr);
127 free_dgst:
128 free(dgst_ptr);
129 free_m:
130 unmap_sysmem(m_ptr);
131
132 } else {
133 return CMD_RET_USAGE;
134 }
135 return ret;
136 }
137
138 /***************************************************/
139 static char mfgprot_help_text[] =
140 "Usage:\n"
141 "Print the public key for Manufacturing Protection\n"
142 "\tmfgprot pubk\n"
143 "Generates a Manufacturing Protection signature\n"
144 "\tmfgprot sign <data_addr> <size>";
145
146 U_BOOT_CMD(
147 mfgprot, 4, 1, do_mfgprot,
148 "Manufacturing Protection\n",
149 mfgprot_help_text
150 );
151