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 <env.h>
16 #include <fsl_sec.h>
17 #include <mapmem.h>
18 #include <memalign.h>
19 
20 /**
21  * do_mfgprot() - Handle the "mfgprot" command-line command
22  * @cmdtp:  Command data struct pointer
23  * @flag:   Command flag
24  * @argc:   Command-line argument count
25  * @argv:   Array of command-line arguments
26  *
27  * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
28  * on error.
29  */
do_mfgprot(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])30 static int do_mfgprot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
31 {
32 	u8 *m_ptr, *dgst_ptr, *c_ptr, *d_ptr, *dst_ptr;
33 	char *pubk, *sign, *sel;
34 	int m_size, i, ret;
35 	u32 m_addr;
36 
37 	pubk = "pubk";
38 	sign = "sign";
39 	sel = argv[1];
40 
41 	/* Enable HAB clock */
42 	hab_caam_clock_enable(1);
43 
44 	u32 out_jr_size = sec_in32(CFG_SYS_FSL_JR0_ADDR +
45 				   FSL_CAAM_ORSR_JRa_OFFSET);
46 
47 	if (out_jr_size != FSL_CAAM_MAX_JR_SIZE)
48 		sec_init();
49 
50 	if (strcmp(sel, pubk) == 0) {
51 		dst_ptr = malloc_cache_aligned(FSL_CAAM_MP_PUBK_BYTES);
52 		if (!dst_ptr)
53 			return -ENOMEM;
54 
55 		ret = gen_mppubk(dst_ptr);
56 		if (ret) {
57 			free(dst_ptr);
58 			return ret;
59 		}
60 
61 		/* Output results */
62 		puts("Public key:\n");
63 		for (i = 0; i < FSL_CAAM_MP_PUBK_BYTES; i++)
64 			printf("%02X", (dst_ptr)[i]);
65 		puts("\n");
66 		free(dst_ptr);
67 
68 	} else if (strcmp(sel, sign) == 0) {
69 		if (argc != 4)
70 			return CMD_RET_USAGE;
71 
72 		m_addr = hextoul(argv[2], NULL);
73 		m_size = dectoul(argv[3], NULL);
74 		m_ptr = map_physmem(m_addr, m_size, MAP_NOCACHE);
75 		if (!m_ptr)
76 			return -ENOMEM;
77 
78 		dgst_ptr = malloc_cache_aligned(FSL_CAAM_MP_MES_DGST_BYTES);
79 		if (!dgst_ptr) {
80 			ret = -ENOMEM;
81 			goto free_m;
82 		}
83 
84 		c_ptr = malloc_cache_aligned(FSL_CAAM_MP_PRVK_BYTES);
85 		if (!c_ptr) {
86 			ret = -ENOMEM;
87 			goto free_dgst;
88 		}
89 
90 		d_ptr = malloc_cache_aligned(FSL_CAAM_MP_PRVK_BYTES);
91 		if (!d_ptr) {
92 			ret = -ENOMEM;
93 			goto free_c;
94 		}
95 
96 		ret = sign_mppubk(m_ptr, m_size, dgst_ptr, c_ptr, d_ptr);
97 		if (ret)
98 			goto free_d;
99 
100 		/* Output results */
101 		puts("Message: ");
102 		for (i = 0; i < m_size; i++)
103 			printf("%02X ", (m_ptr)[i]);
104 		puts("\n");
105 
106 		puts("Message Representative Digest(SHA-256):\n");
107 		for (i = 0; i < FSL_CAAM_MP_MES_DGST_BYTES; i++)
108 			printf("%02X", (dgst_ptr)[i]);
109 		puts("\n");
110 
111 		puts("Signature:\n");
112 		puts("C:\n");
113 		for (i = 0; i < FSL_CAAM_MP_PRVK_BYTES; i++)
114 			printf("%02X", (c_ptr)[i]);
115 		puts("\n");
116 
117 		puts("d:\n");
118 		for (i = 0; i < FSL_CAAM_MP_PRVK_BYTES; i++)
119 			printf("%02X", (d_ptr)[i]);
120 		puts("\n");
121 free_d:
122 	free(d_ptr);
123 free_c:
124 	free(c_ptr);
125 free_dgst:
126 	free(dgst_ptr);
127 free_m:
128 	unmap_sysmem(m_ptr);
129 
130 	} else {
131 		return CMD_RET_USAGE;
132 	}
133 	return ret;
134 }
135 
136 /***************************************************/
137 static char mfgprot_help_text[] =
138 	"Usage:\n"
139 	 "Print the public key for Manufacturing Protection\n"
140 	 "\tmfgprot pubk\n"
141 	 "Generates a Manufacturing Protection signature\n"
142 	 "\tmfgprot sign <data_addr> <size>";
143 
144 U_BOOT_CMD(
145 	mfgprot, 4, 1, do_mfgprot,
146 	"Manufacturing Protection\n",
147 	mfgprot_help_text
148 );
149