ec8a8756f7fc07d0231dcdae43ecbc6efb1914ef
[platform/kernel/u-boot.git] / arch / arm / mach-imx / cmd_mfgprot.c
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  */
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(CONFIG_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 );