~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/tools/image-host.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2013, Google Inc.
 
3
 *
 
4
 * (C) Copyright 2008 Semihalf
 
5
 *
 
6
 * (C) Copyright 2000-2006
 
7
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
8
 *
 
9
 * SPDX-License-Identifier:     GPL-2.0+
 
10
 */
 
11
 
 
12
#include "mkimage.h"
 
13
#include <image.h>
 
14
#include <version.h>
 
15
 
 
16
/**
 
17
 * fit_set_hash_value - set hash value in requested has node
 
18
 * @fit: pointer to the FIT format image header
 
19
 * @noffset: hash node offset
 
20
 * @value: hash value to be set
 
21
 * @value_len: hash value length
 
22
 *
 
23
 * fit_set_hash_value() attempts to set hash value in a node at offset
 
24
 * given and returns operation status to the caller.
 
25
 *
 
26
 * returns
 
27
 *     0, on success
 
28
 *     -1, on failure
 
29
 */
 
30
static int fit_set_hash_value(void *fit, int noffset, uint8_t *value,
 
31
                                int value_len)
 
32
{
 
33
        int ret;
 
34
 
 
35
        ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len);
 
36
        if (ret) {
 
37
                printf("Can't set hash '%s' property for '%s' node(%s)\n",
 
38
                       FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL),
 
39
                       fdt_strerror(ret));
 
40
                return -1;
 
41
        }
 
42
 
 
43
        return 0;
 
44
}
 
45
 
 
46
/**
 
47
 * fit_image_process_hash - Process a single subnode of the images/ node
 
48
 *
 
49
 * Check each subnode and process accordingly. For hash nodes we generate
 
50
 * a hash of the supplised data and store it in the node.
 
51
 *
 
52
 * @fit:        pointer to the FIT format image header
 
53
 * @image_name: name of image being processes (used to display errors)
 
54
 * @noffset:    subnode offset
 
55
 * @data:       data to process
 
56
 * @size:       size of data in bytes
 
57
 * @return 0 if ok, -1 on error
 
58
 */
 
59
static int fit_image_process_hash(void *fit, const char *image_name,
 
60
                int noffset, const void *data, size_t size)
 
61
{
 
62
        uint8_t value[FIT_MAX_HASH_LEN];
 
63
        const char *node_name;
 
64
        int value_len;
 
65
        char *algo;
 
66
 
 
67
        node_name = fit_get_name(fit, noffset, NULL);
 
68
 
 
69
        if (fit_image_hash_get_algo(fit, noffset, &algo)) {
 
70
                printf("Can't get hash algo property for '%s' hash node in '%s' image node\n",
 
71
                       node_name, image_name);
 
72
                return -1;
 
73
        }
 
74
 
 
75
        if (calculate_hash(data, size, algo, value, &value_len)) {
 
76
                printf("Unsupported hash algorithm (%s) for '%s' hash node in '%s' image node\n",
 
77
                       algo, node_name, image_name);
 
78
                return -1;
 
79
        }
 
80
 
 
81
        if (fit_set_hash_value(fit, noffset, value, value_len)) {
 
82
                printf("Can't set hash value for '%s' hash node in '%s' image node\n",
 
83
                       node_name, image_name);
 
84
                return -1;
 
85
        }
 
86
 
 
87
        return 0;
 
88
}
 
89
 
 
90
/**
 
91
 * fit_image_write_sig() - write the signature to a FIT
 
92
 *
 
93
 * This writes the signature and signer data to the FIT.
 
94
 *
 
95
 * @fit: pointer to the FIT format image header
 
96
 * @noffset: hash node offset
 
97
 * @value: signature value to be set
 
98
 * @value_len: signature value length
 
99
 * @comment: Text comment to write (NULL for none)
 
100
 *
 
101
 * returns
 
102
 *     0, on success
 
103
 *     -FDT_ERR_..., on failure
 
104
 */
 
105
static int fit_image_write_sig(void *fit, int noffset, uint8_t *value,
 
106
                int value_len, const char *comment, const char *region_prop,
 
107
                int region_proplen)
 
108
{
 
109
        int string_size;
 
110
        int ret;
 
111
 
 
112
        /*
 
113
         * Get the current string size, before we update the FIT and add
 
114
         * more
 
115
         */
 
116
        string_size = fdt_size_dt_strings(fit);
 
117
 
 
118
        ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len);
 
119
        if (!ret) {
 
120
                ret = fdt_setprop_string(fit, noffset, "signer-name",
 
121
                                         "mkimage");
 
122
        }
 
123
        if (!ret) {
 
124
                ret = fdt_setprop_string(fit, noffset, "signer-version",
 
125
                                  PLAIN_VERSION);
 
126
        }
 
127
        if (comment && !ret)
 
128
                ret = fdt_setprop_string(fit, noffset, "comment", comment);
 
129
        if (!ret)
 
130
                ret = fit_set_timestamp(fit, noffset, time(NULL));
 
131
        if (region_prop && !ret) {
 
132
                uint32_t strdata[2];
 
133
 
 
134
                ret = fdt_setprop(fit, noffset, "hashed-nodes",
 
135
                                   region_prop, region_proplen);
 
136
                strdata[0] = 0;
 
137
                strdata[1] = cpu_to_fdt32(string_size);
 
138
                if (!ret) {
 
139
                        ret = fdt_setprop(fit, noffset, "hashed-strings",
 
140
                                          strdata, sizeof(strdata));
 
141
                }
 
142
        }
 
143
 
 
144
        return ret;
 
145
}
 
146
 
 
147
static int fit_image_setup_sig(struct image_sign_info *info,
 
148
                const char *keydir, void *fit, const char *image_name,
 
149
                int noffset, const char *require_keys)
 
150
{
 
151
        const char *node_name;
 
152
        char *algo_name;
 
153
 
 
154
        node_name = fit_get_name(fit, noffset, NULL);
 
155
        if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
 
156
                printf("Can't get algo property for '%s' signature node in '%s' image node\n",
 
157
                       node_name, image_name);
 
158
                return -1;
 
159
        }
 
160
 
 
161
        memset(info, '\0', sizeof(*info));
 
162
        info->keydir = keydir;
 
163
        info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
 
164
        info->fit = fit;
 
165
        info->node_offset = noffset;
 
166
        info->algo = image_get_sig_algo(algo_name);
 
167
        info->require_keys = require_keys;
 
168
        if (!info->algo) {
 
169
                printf("Unsupported signature algorithm (%s) for '%s' signature node in '%s' image node\n",
 
170
                       algo_name, node_name, image_name);
 
171
                return -1;
 
172
        }
 
173
 
 
174
        return 0;
 
175
}
 
176
 
 
177
/**
 
178
 * fit_image_process_sig- Process a single subnode of the images/ node
 
179
 *
 
180
 * Check each subnode and process accordingly. For signature nodes we
 
181
 * generate a signed hash of the supplised data and store it in the node.
 
182
 *
 
183
 * @keydir:     Directory containing keys to use for signing
 
184
 * @keydest:    Destination FDT blob to write public keys into
 
185
 * @fit:        pointer to the FIT format image header
 
186
 * @image_name: name of image being processes (used to display errors)
 
187
 * @noffset:    subnode offset
 
188
 * @data:       data to process
 
189
 * @size:       size of data in bytes
 
190
 * @comment:    Comment to add to signature nodes
 
191
 * @require_keys: Mark all keys as 'required'
 
192
 * @return 0 if ok, -1 on error
 
193
 */
 
194
static int fit_image_process_sig(const char *keydir, void *keydest,
 
195
                void *fit, const char *image_name,
 
196
                int noffset, const void *data, size_t size,
 
197
                const char *comment, int require_keys)
 
198
{
 
199
        struct image_sign_info info;
 
200
        struct image_region region;
 
201
        const char *node_name;
 
202
        uint8_t *value;
 
203
        uint value_len;
 
204
        int ret;
 
205
 
 
206
        if (fit_image_setup_sig(&info, keydir, fit, image_name, noffset,
 
207
                                require_keys ? "image" : NULL))
 
208
                return -1;
 
209
 
 
210
        node_name = fit_get_name(fit, noffset, NULL);
 
211
        region.data = data;
 
212
        region.size = size;
 
213
        ret = info.algo->sign(&info, &region, 1, &value, &value_len);
 
214
        if (ret) {
 
215
                printf("Failed to sign '%s' signature node in '%s' image node: %d\n",
 
216
                       node_name, image_name, ret);
 
217
 
 
218
                /* We allow keys to be missing */
 
219
                if (ret == -ENOENT)
 
220
                        return 0;
 
221
                return -1;
 
222
        }
 
223
 
 
224
        ret = fit_image_write_sig(fit, noffset, value, value_len, comment,
 
225
                        NULL, 0);
 
226
        if (ret) {
 
227
                printf("Can't write signature for '%s' signature node in '%s' image node: %s\n",
 
228
                       node_name, image_name, fdt_strerror(ret));
 
229
                return -1;
 
230
        }
 
231
        free(value);
 
232
 
 
233
        /* Get keyname again, as FDT has changed and invalidated our pointer */
 
234
        info.keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
 
235
 
 
236
        /* Write the public key into the supplied FDT file */
 
237
        if (keydest && info.algo->add_verify_data(&info, keydest)) {
 
238
                printf("Failed to add verification data for '%s' signature node in '%s' image node\n",
 
239
                       node_name, image_name);
 
240
                return -1;
 
241
        }
 
242
 
 
243
        return 0;
 
244
}
 
245
 
 
246
/**
 
247
 * fit_image_add_verification_data() - calculate/set verig. data for image node
 
248
 *
 
249
 * This adds hash and signature values for an component image node.
 
250
 *
 
251
 * All existing hash subnodes are checked, if algorithm property is set to
 
252
 * one of the supported hash algorithms, hash value is computed and
 
253
 * corresponding hash node property is set, for example:
 
254
 *
 
255
 * Input component image node structure:
 
256
 *
 
257
 * o image@1 (at image_noffset)
 
258
 *   | - data = [binary data]
 
259
 *   o hash@1
 
260
 *     |- algo = "sha1"
 
261
 *
 
262
 * Output component image node structure:
 
263
 *
 
264
 * o image@1 (at image_noffset)
 
265
 *   | - data = [binary data]
 
266
 *   o hash@1
 
267
 *     |- algo = "sha1"
 
268
 *     |- value = sha1(data)
 
269
 *
 
270
 * For signature details, please see doc/uImage.FIT/signature.txt
 
271
 *
 
272
 * @keydir      Directory containing *.key and *.crt files (or NULL)
 
273
 * @keydest     FDT Blob to write public keys into (NULL if none)
 
274
 * @fit:        Pointer to the FIT format image header
 
275
 * @image_noffset: Requested component image node
 
276
 * @comment:    Comment to add to signature nodes
 
277
 * @require_keys: Mark all keys as 'required'
 
278
 * @return: 0 on success, <0 on failure
 
279
 */
 
280
int fit_image_add_verification_data(const char *keydir, void *keydest,
 
281
                void *fit, int image_noffset, const char *comment,
 
282
                int require_keys)
 
283
{
 
284
        const char *image_name;
 
285
        const void *data;
 
286
        size_t size;
 
287
        int noffset;
 
288
 
 
289
        /* Get image data and data length */
 
290
        if (fit_image_get_data(fit, image_noffset, &data, &size)) {
 
291
                printf("Can't get image data/size\n");
 
292
                return -1;
 
293
        }
 
294
 
 
295
        image_name = fit_get_name(fit, image_noffset, NULL);
 
296
 
 
297
        /* Process all hash subnodes of the component image node */
 
298
        for (noffset = fdt_first_subnode(fit, image_noffset);
 
299
             noffset >= 0;
 
300
             noffset = fdt_next_subnode(fit, noffset)) {
 
301
                const char *node_name;
 
302
                int ret = 0;
 
303
 
 
304
                /*
 
305
                 * Check subnode name, must be equal to "hash" or "signature".
 
306
                 * Multiple hash nodes require unique unit node
 
307
                 * names, e.g. hash@1, hash@2, signature@1, etc.
 
308
                 */
 
309
                node_name = fit_get_name(fit, noffset, NULL);
 
310
                if (!strncmp(node_name, FIT_HASH_NODENAME,
 
311
                             strlen(FIT_HASH_NODENAME))) {
 
312
                        ret = fit_image_process_hash(fit, image_name, noffset,
 
313
                                                data, size);
 
314
                } else if (IMAGE_ENABLE_SIGN && keydir &&
 
315
                           !strncmp(node_name, FIT_SIG_NODENAME,
 
316
                                strlen(FIT_SIG_NODENAME))) {
 
317
                        ret = fit_image_process_sig(keydir, keydest,
 
318
                                fit, image_name, noffset, data, size,
 
319
                                comment, require_keys);
 
320
                }
 
321
                if (ret)
 
322
                        return -1;
 
323
        }
 
324
 
 
325
        return 0;
 
326
}
 
327
 
 
328
struct strlist {
 
329
        int count;
 
330
        char **strings;
 
331
};
 
332
 
 
333
static void strlist_init(struct strlist *list)
 
334
{
 
335
        memset(list, '\0', sizeof(*list));
 
336
}
 
337
 
 
338
static void strlist_free(struct strlist *list)
 
339
{
 
340
        int i;
 
341
 
 
342
        for (i = 0; i < list->count; i++)
 
343
                free(list->strings[i]);
 
344
        free(list->strings);
 
345
}
 
346
 
 
347
static int strlist_add(struct strlist *list, const char *str)
 
348
{
 
349
        char *dup;
 
350
 
 
351
        dup = strdup(str);
 
352
        list->strings = realloc(list->strings,
 
353
                                (list->count + 1) * sizeof(char *));
 
354
        if (!list || !str)
 
355
                return -1;
 
356
        list->strings[list->count++] = dup;
 
357
 
 
358
        return 0;
 
359
}
 
360
 
 
361
static const char *fit_config_get_image_list(void *fit, int noffset,
 
362
                int *lenp, int *allow_missingp)
 
363
{
 
364
        static const char default_list[] = FIT_KERNEL_PROP "\0"
 
365
                        FIT_FDT_PROP;
 
366
        const char *prop;
 
367
 
 
368
        /* If there is an "image" property, use that */
 
369
        prop = fdt_getprop(fit, noffset, "sign-images", lenp);
 
370
        if (prop) {
 
371
                *allow_missingp = 0;
 
372
                return *lenp ? prop : NULL;
 
373
        }
 
374
 
 
375
        /* Default image list */
 
376
        *allow_missingp = 1;
 
377
        *lenp = sizeof(default_list);
 
378
 
 
379
        return default_list;
 
380
}
 
381
 
 
382
static int fit_config_get_hash_list(void *fit, int conf_noffset,
 
383
                                    int sig_offset, struct strlist *node_inc)
 
384
{
 
385
        int allow_missing;
 
386
        const char *prop, *iname, *end;
 
387
        const char *conf_name, *sig_name;
 
388
        char name[200], path[200];
 
389
        int image_count;
 
390
        int ret, len;
 
391
 
 
392
        conf_name = fit_get_name(fit, conf_noffset, NULL);
 
393
        sig_name = fit_get_name(fit, sig_offset, NULL);
 
394
 
 
395
        /*
 
396
         * Build a list of nodes we need to hash. We always need the root
 
397
         * node and the configuration.
 
398
         */
 
399
        strlist_init(node_inc);
 
400
        snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH, conf_name);
 
401
        if (strlist_add(node_inc, "/") ||
 
402
            strlist_add(node_inc, name))
 
403
                goto err_mem;
 
404
 
 
405
        /* Get a list of images that we intend to sign */
 
406
        prop = fit_config_get_image_list(fit, sig_offset, &len,
 
407
                                        &allow_missing);
 
408
        if (!prop)
 
409
                return 0;
 
410
 
 
411
        /* Locate the images */
 
412
        end = prop + len;
 
413
        image_count = 0;
 
414
        for (iname = prop; iname < end; iname += strlen(iname) + 1) {
 
415
                int noffset;
 
416
                int image_noffset;
 
417
                int hash_count;
 
418
 
 
419
                image_noffset = fit_conf_get_prop_node(fit, conf_noffset,
 
420
                                                       iname);
 
421
                if (image_noffset < 0) {
 
422
                        printf("Failed to find image '%s' in  configuration '%s/%s'\n",
 
423
                               iname, conf_name, sig_name);
 
424
                        if (allow_missing)
 
425
                                continue;
 
426
 
 
427
                        return -ENOENT;
 
428
                }
 
429
 
 
430
                ret = fdt_get_path(fit, image_noffset, path, sizeof(path));
 
431
                if (ret < 0)
 
432
                        goto err_path;
 
433
                if (strlist_add(node_inc, path))
 
434
                        goto err_mem;
 
435
 
 
436
                snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH,
 
437
                         conf_name);
 
438
 
 
439
                /* Add all this image's hashes */
 
440
                hash_count = 0;
 
441
                for (noffset = fdt_first_subnode(fit, image_noffset);
 
442
                     noffset >= 0;
 
443
                     noffset = fdt_next_subnode(fit, noffset)) {
 
444
                        const char *name = fit_get_name(fit, noffset, NULL);
 
445
 
 
446
                        if (strncmp(name, FIT_HASH_NODENAME,
 
447
                                    strlen(FIT_HASH_NODENAME)))
 
448
                                continue;
 
449
                        ret = fdt_get_path(fit, noffset, path, sizeof(path));
 
450
                        if (ret < 0)
 
451
                                goto err_path;
 
452
                        if (strlist_add(node_inc, path))
 
453
                                goto err_mem;
 
454
                        hash_count++;
 
455
                }
 
456
 
 
457
                if (!hash_count) {
 
458
                        printf("Failed to find any hash nodes in configuration '%s/%s' image '%s' - without these it is not possible to verify this image\n",
 
459
                               conf_name, sig_name, iname);
 
460
                        return -ENOMSG;
 
461
                }
 
462
 
 
463
                image_count++;
 
464
        }
 
465
 
 
466
        if (!image_count) {
 
467
                printf("Failed to find any images for configuration '%s/%s'\n",
 
468
                       conf_name, sig_name);
 
469
                return -ENOMSG;
 
470
        }
 
471
 
 
472
        return 0;
 
473
 
 
474
err_mem:
 
475
        printf("Out of memory processing configuration '%s/%s'\n", conf_name,
 
476
               sig_name);
 
477
        return -ENOMEM;
 
478
 
 
479
err_path:
 
480
        printf("Failed to get path for image '%s' in configuration '%s/%s': %s\n",
 
481
               iname, conf_name, sig_name, fdt_strerror(ret));
 
482
        return -ENOENT;
 
483
}
 
484
 
 
485
static int fit_config_get_data(void *fit, int conf_noffset, int noffset,
 
486
                struct image_region **regionp, int *region_countp,
 
487
                char **region_propp, int *region_proplen)
 
488
{
 
489
        char * const exc_prop[] = {"data"};
 
490
        struct strlist node_inc;
 
491
        struct image_region *region;
 
492
        struct fdt_region fdt_regions[100];
 
493
        const char *conf_name, *sig_name;
 
494
        char path[200];
 
495
        int count, i;
 
496
        char *region_prop;
 
497
        int ret, len;
 
498
 
 
499
        conf_name = fit_get_name(fit, conf_noffset, NULL);
 
500
        sig_name = fit_get_name(fit, conf_noffset, NULL);
 
501
        debug("%s: conf='%s', sig='%s'\n", __func__, conf_name, sig_name);
 
502
 
 
503
        /* Get a list of nodes we want to hash */
 
504
        ret = fit_config_get_hash_list(fit, conf_noffset, noffset, &node_inc);
 
505
        if (ret)
 
506
                return ret;
 
507
 
 
508
        /* Get a list of regions to hash */
 
509
        count = fdt_find_regions(fit, node_inc.strings, node_inc.count,
 
510
                        exc_prop, ARRAY_SIZE(exc_prop),
 
511
                        fdt_regions, ARRAY_SIZE(fdt_regions),
 
512
                        path, sizeof(path), 1);
 
513
        if (count < 0) {
 
514
                printf("Failed to hash configuration '%s/%s': %s\n", conf_name,
 
515
                       sig_name, fdt_strerror(ret));
 
516
                return -EIO;
 
517
        }
 
518
        if (count == 0) {
 
519
                printf("No data to hash for configuration '%s/%s': %s\n",
 
520
                       conf_name, sig_name, fdt_strerror(ret));
 
521
                return -EINVAL;
 
522
        }
 
523
 
 
524
        /* Build our list of data blocks */
 
525
        region = fit_region_make_list(fit, fdt_regions, count, NULL);
 
526
        if (!region) {
 
527
                printf("Out of memory hashing configuration '%s/%s'\n",
 
528
                       conf_name, sig_name);
 
529
                return -ENOMEM;
 
530
        }
 
531
 
 
532
        /* Create a list of all hashed properties */
 
533
        debug("Hash nodes:\n");
 
534
        for (i = len = 0; i < node_inc.count; i++) {
 
535
                debug("   %s\n", node_inc.strings[i]);
 
536
                len += strlen(node_inc.strings[i]) + 1;
 
537
        }
 
538
        region_prop = malloc(len);
 
539
        if (!region_prop) {
 
540
                printf("Out of memory setting up regions for configuration '%s/%s'\n",
 
541
                       conf_name, sig_name);
 
542
                return -ENOMEM;
 
543
        }
 
544
        for (i = len = 0; i < node_inc.count;
 
545
             len += strlen(node_inc.strings[i]) + 1, i++)
 
546
                strcpy(region_prop + len, node_inc.strings[i]);
 
547
        strlist_free(&node_inc);
 
548
 
 
549
        *region_countp = count;
 
550
        *regionp = region;
 
551
        *region_propp = region_prop;
 
552
        *region_proplen = len;
 
553
 
 
554
        return 0;
 
555
}
 
556
 
 
557
static int fit_config_process_sig(const char *keydir, void *keydest,
 
558
                void *fit, const char *conf_name, int conf_noffset,
 
559
                int noffset, const char *comment, int require_keys)
 
560
{
 
561
        struct image_sign_info info;
 
562
        const char *node_name;
 
563
        struct image_region *region;
 
564
        char *region_prop;
 
565
        int region_proplen;
 
566
        int region_count;
 
567
        uint8_t *value;
 
568
        uint value_len;
 
569
        int ret;
 
570
 
 
571
        node_name = fit_get_name(fit, noffset, NULL);
 
572
        if (fit_config_get_data(fit, conf_noffset, noffset, &region,
 
573
                                &region_count, &region_prop, &region_proplen))
 
574
                return -1;
 
575
 
 
576
        if (fit_image_setup_sig(&info, keydir, fit, conf_name, noffset,
 
577
                                require_keys ? "conf" : NULL))
 
578
                return -1;
 
579
 
 
580
        ret = info.algo->sign(&info, region, region_count, &value, &value_len);
 
581
        free(region);
 
582
        if (ret) {
 
583
                printf("Failed to sign '%s' signature node in '%s' conf node\n",
 
584
                       node_name, conf_name);
 
585
 
 
586
                /* We allow keys to be missing */
 
587
                if (ret == -ENOENT)
 
588
                        return 0;
 
589
                return -1;
 
590
        }
 
591
 
 
592
        if (fit_image_write_sig(fit, noffset, value, value_len, comment,
 
593
                                region_prop, region_proplen)) {
 
594
                printf("Can't write signature for '%s' signature node in '%s' conf node\n",
 
595
                       node_name, conf_name);
 
596
                return -1;
 
597
        }
 
598
        free(value);
 
599
        free(region_prop);
 
600
 
 
601
        /* Get keyname again, as FDT has changed and invalidated our pointer */
 
602
        info.keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
 
603
 
 
604
        /* Write the public key into the supplied FDT file */
 
605
        if (keydest && info.algo->add_verify_data(&info, keydest)) {
 
606
                printf("Failed to add verification data for '%s' signature node in '%s' image node\n",
 
607
                       node_name, conf_name);
 
608
                return -1;
 
609
        }
 
610
 
 
611
        return 0;
 
612
}
 
613
 
 
614
static int fit_config_add_verification_data(const char *keydir, void *keydest,
 
615
                void *fit, int conf_noffset, const char *comment,
 
616
                int require_keys)
 
617
{
 
618
        const char *conf_name;
 
619
        int noffset;
 
620
 
 
621
        conf_name = fit_get_name(fit, conf_noffset, NULL);
 
622
 
 
623
        /* Process all hash subnodes of the configuration node */
 
624
        for (noffset = fdt_first_subnode(fit, conf_noffset);
 
625
             noffset >= 0;
 
626
             noffset = fdt_next_subnode(fit, noffset)) {
 
627
                const char *node_name;
 
628
                int ret = 0;
 
629
 
 
630
                node_name = fit_get_name(fit, noffset, NULL);
 
631
                if (!strncmp(node_name, FIT_SIG_NODENAME,
 
632
                             strlen(FIT_SIG_NODENAME))) {
 
633
                        ret = fit_config_process_sig(keydir, keydest,
 
634
                                fit, conf_name, conf_noffset, noffset, comment,
 
635
                                require_keys);
 
636
                }
 
637
                if (ret)
 
638
                        return ret;
 
639
        }
 
640
 
 
641
        return 0;
 
642
}
 
643
 
 
644
int fit_add_verification_data(const char *keydir, void *keydest, void *fit,
 
645
                              const char *comment, int require_keys)
 
646
{
 
647
        int images_noffset, confs_noffset;
 
648
        int noffset;
 
649
        int ret;
 
650
 
 
651
        /* Find images parent node offset */
 
652
        images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
 
653
        if (images_noffset < 0) {
 
654
                printf("Can't find images parent node '%s' (%s)\n",
 
655
                       FIT_IMAGES_PATH, fdt_strerror(images_noffset));
 
656
                return images_noffset;
 
657
        }
 
658
 
 
659
        /* Process its subnodes, print out component images details */
 
660
        for (noffset = fdt_first_subnode(fit, images_noffset);
 
661
             noffset >= 0;
 
662
             noffset = fdt_next_subnode(fit, noffset)) {
 
663
                /*
 
664
                 * Direct child node of the images parent node,
 
665
                 * i.e. component image node.
 
666
                 */
 
667
                ret = fit_image_add_verification_data(keydir, keydest,
 
668
                                fit, noffset, comment, require_keys);
 
669
                if (ret)
 
670
                        return ret;
 
671
        }
 
672
 
 
673
        /* If there are no keys, we can't sign configurations */
 
674
        if (!IMAGE_ENABLE_SIGN || !keydir)
 
675
                return 0;
 
676
 
 
677
        /* Find configurations parent node offset */
 
678
        confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
 
679
        if (confs_noffset < 0) {
 
680
                printf("Can't find images parent node '%s' (%s)\n",
 
681
                       FIT_IMAGES_PATH, fdt_strerror(confs_noffset));
 
682
                return -ENOENT;
 
683
        }
 
684
 
 
685
        /* Process its subnodes, print out component images details */
 
686
        for (noffset = fdt_first_subnode(fit, confs_noffset);
 
687
             noffset >= 0;
 
688
             noffset = fdt_next_subnode(fit, noffset)) {
 
689
                ret = fit_config_add_verification_data(keydir, keydest,
 
690
                                                       fit, noffset, comment,
 
691
                                                       require_keys);
 
692
                if (ret)
 
693
                        return ret;
 
694
        }
 
695
 
 
696
        return 0;
 
697
}
 
698
 
 
699
#ifdef CONFIG_FIT_SIGNATURE
 
700
int fit_check_sign(const void *working_fdt, const void *key)
 
701
{
 
702
        int cfg_noffset;
 
703
        int ret;
 
704
 
 
705
        cfg_noffset = fit_conf_get_node(working_fdt, NULL);
 
706
        if (!cfg_noffset)
 
707
                return -1;
 
708
 
 
709
        ret = fit_config_verify(working_fdt, cfg_noffset);
 
710
        return ret;
 
711
}
 
712
#endif