2 * Copyright (c) 2013, Google Inc.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 DECLARE_GLOBAL_DATA_PTR
;
27 #endif /* !USE_HOSTCC*/
32 struct image_sig_algo image_sig_algos
[] = {
41 struct image_sig_algo
*image_get_sig_algo(const char *name
)
45 for (i
= 0; i
< ARRAY_SIZE(image_sig_algos
); i
++) {
46 if (!strcmp(image_sig_algos
[i
].name
, name
))
47 return &image_sig_algos
[i
];
53 static int fit_image_setup_verify(struct image_sign_info
*info
,
54 const void *fit
, int noffset
, int required_keynode
,
59 if (fit_image_hash_get_algo(fit
, noffset
, &algo_name
)) {
60 *err_msgp
= "Can't get hash algo property";
63 memset(info
, '\0', sizeof(*info
));
64 info
->keyname
= fdt_getprop(fit
, noffset
, "key-name-hint", NULL
);
65 info
->fit
= (void *)fit
;
66 info
->node_offset
= noffset
;
67 info
->algo
= image_get_sig_algo(algo_name
);
68 info
->fdt_blob
= gd_fdt_blob();
69 info
->required_keynode
= required_keynode
;
70 printf("%s:%s", algo_name
, info
->keyname
);
73 *err_msgp
= "Unknown signature algorithm";
80 int fit_image_check_sig(const void *fit
, int noffset
, const void *data
,
81 size_t size
, int required_keynode
, char **err_msgp
)
83 struct image_sign_info info
;
84 struct image_region region
;
89 if (fit_image_setup_verify(&info
, fit
, noffset
, required_keynode
,
93 if (fit_image_hash_get_value(fit
, noffset
, &fit_value
,
95 *err_msgp
= "Can't get hash value property";
102 if (info
.algo
->verify(&info
, ®ion
, 1, fit_value
, fit_value_len
)) {
103 *err_msgp
= "Verification failed";
110 static int fit_image_verify_sig(const void *fit
, int image_noffset
,
111 const char *data
, size_t size
, const void *sig_blob
,
119 /* Process all hash subnodes of the component image node */
120 for (noffset
= fdt_first_subnode(fit
, image_noffset
);
122 noffset
= fdt_next_subnode(fit
, noffset
)) {
123 const char *name
= fit_get_name(fit
, noffset
, NULL
);
125 if (!strncmp(name
, FIT_SIG_NODENAME
,
126 strlen(FIT_SIG_NODENAME
))) {
127 ret
= fit_image_check_sig(fit
, noffset
, data
,
139 if (noffset
== -FDT_ERR_TRUNCATED
|| noffset
== -FDT_ERR_BADSTRUCTURE
) {
140 err_msg
= "Corrupted or truncated tree";
144 return verified
? 0 : -EPERM
;
147 printf(" error!\n%s for '%s' hash node in '%s' image node\n",
148 err_msg
, fit_get_name(fit
, noffset
, NULL
),
149 fit_get_name(fit
, image_noffset
, NULL
));
153 int fit_image_verify_required_sigs(const void *fit
, int image_noffset
,
154 const char *data
, size_t size
, const void *sig_blob
,
157 int verify_count
= 0;
161 /* Work out what we need to verify */
163 sig_node
= fdt_subnode_offset(sig_blob
, 0, FIT_SIG_NODENAME
);
165 debug("%s: No signature node found: %s\n", __func__
,
166 fdt_strerror(sig_node
));
170 for (noffset
= fdt_first_subnode(sig_blob
, sig_node
);
172 noffset
= fdt_next_subnode(sig_blob
, noffset
)) {
173 const char *required
;
176 required
= fdt_getprop(sig_blob
, noffset
, "required", NULL
);
177 if (!required
|| strcmp(required
, "image"))
179 ret
= fit_image_verify_sig(fit
, image_noffset
, data
, size
,
182 printf("Failed to verify required signature '%s'\n",
183 fit_get_name(sig_blob
, noffset
, NULL
));