uboot/lib/rsa/rsa-verify.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2013, Google Inc.
   4 */
   5
   6#ifndef USE_HOSTCC
   7#include <common.h>
   8#include <fdtdec.h>
   9#include <log.h>
  10#include <malloc.h>
  11#include <asm/types.h>
  12#include <asm/byteorder.h>
  13#include <linux/errno.h>
  14#include <asm/types.h>
  15#include <asm/unaligned.h>
  16#include <dm.h>
  17#else
  18#include "fdt_host.h"
  19#include "mkimage.h"
  20#include <fdt_support.h>
  21#endif
  22#include <linux/kconfig.h>
  23#include <u-boot/rsa-mod-exp.h>
  24#include <u-boot/rsa.h>
  25
  26#ifndef __UBOOT__
  27/*
  28 * NOTE:
  29 * Since host tools, like mkimage, make use of openssl library for
  30 * RSA encryption, rsa_verify_with_pkey()/rsa_gen_key_prop() are
  31 * of no use and should not be compiled in.
  32 * So just turn off CONFIG_RSA_VERIFY_WITH_PKEY.
  33 */
  34
  35#undef CONFIG_RSA_VERIFY_WITH_PKEY
  36#endif
  37
  38/* Default public exponent for backward compatibility */
  39#define RSA_DEFAULT_PUBEXP      65537
  40
  41/**
  42 * rsa_verify_padding() - Verify RSA message padding is valid
  43 *
  44 * Verify a RSA message's padding is consistent with PKCS1.5
  45 * padding as described in the RSA PKCS#1 v2.1 standard.
  46 *
  47 * @msg:        Padded message
  48 * @pad_len:    Number of expected padding bytes
  49 * @algo:       Checksum algo structure having information on DER encoding etc.
  50 * @return 0 on success, != 0 on failure
  51 */
  52static int rsa_verify_padding(const uint8_t *msg, const int pad_len,
  53                              struct checksum_algo *algo)
  54{
  55        int ff_len;
  56        int ret;
  57
  58        /* first byte must be 0x00 */
  59        ret = *msg++;
  60        /* second byte must be 0x01 */
  61        ret |= *msg++ ^ 0x01;
  62        /* next ff_len bytes must be 0xff */
  63        ff_len = pad_len - algo->der_len - 3;
  64        ret |= *msg ^ 0xff;
  65        ret |= memcmp(msg, msg+1, ff_len-1);
  66        msg += ff_len;
  67        /* next byte must be 0x00 */
  68        ret |= *msg++;
  69        /* next der_len bytes must match der_prefix */
  70        ret |= memcmp(msg, algo->der_prefix, algo->der_len);
  71
  72        return ret;
  73}
  74
  75int padding_pkcs_15_verify(struct image_sign_info *info,
  76                           uint8_t *msg, int msg_len,
  77                           const uint8_t *hash, int hash_len)
  78{
  79        struct checksum_algo *checksum = info->checksum;
  80        int ret, pad_len = msg_len - checksum->checksum_len;
  81
  82        /* Check pkcs1.5 padding bytes. */
  83        ret = rsa_verify_padding(msg, pad_len, checksum);
  84        if (ret) {
  85                debug("In RSAVerify(): Padding check failed!\n");
  86                return -EINVAL;
  87        }
  88
  89        /* Check hash. */
  90        if (memcmp((uint8_t *)msg + pad_len, hash, msg_len - pad_len)) {
  91                debug("In RSAVerify(): Hash check failed!\n");
  92                return -EACCES;
  93        }
  94
  95        return 0;
  96}
  97
  98#ifndef USE_HOSTCC
  99U_BOOT_PADDING_ALGO(pkcs_15) = {
 100        .name = "pkcs-1.5",
 101        .verify = padding_pkcs_15_verify,
 102};
 103#endif
 104
 105#if CONFIG_IS_ENABLED(FIT_RSASSA_PSS)
 106static void u32_i2osp(uint32_t val, uint8_t *buf)
 107{
 108        buf[0] = (uint8_t)((val >> 24) & 0xff);
 109        buf[1] = (uint8_t)((val >> 16) & 0xff);
 110        buf[2] = (uint8_t)((val >>  8) & 0xff);
 111        buf[3] = (uint8_t)((val >>  0) & 0xff);
 112}
 113
 114/**
 115 * mask_generation_function1() - generate an octet string
 116 *
 117 * Generate an octet string used to check rsa signature.
 118 * It use an input octet string and a hash function.
 119 *
 120 * @checksum:   A Hash function
 121 * @seed:       Specifies an input variable octet string
 122 * @seed_len:   Size of the input octet string
 123 * @output:     Specifies the output octet string
 124 * @output_len: Size of the output octet string
 125 * @return 0 if the octet string was correctly generated, others on error
 126 */
 127static int mask_generation_function1(struct checksum_algo *checksum,
 128                                     uint8_t *seed, int seed_len,
 129                                     uint8_t *output, int output_len)
 130{
 131        struct image_region region[2];
 132        int ret = 0, i, i_output = 0, region_count = 2;
 133        uint32_t counter = 0;
 134        uint8_t buf_counter[4], *tmp;
 135        int hash_len = checksum->checksum_len;
 136
 137        memset(output, 0, output_len);
 138
 139        region[0].data = seed;
 140        region[0].size = seed_len;
 141        region[1].data = &buf_counter[0];
 142        region[1].size = 4;
 143
 144        tmp = malloc(hash_len);
 145        if (!tmp) {
 146                debug("%s: can't allocate array tmp\n", __func__);
 147                ret = -ENOMEM;
 148                goto out;
 149        }
 150
 151        while (i_output < output_len) {
 152                u32_i2osp(counter, &buf_counter[0]);
 153
 154                ret = checksum->calculate(checksum->name,
 155                                          region, region_count,
 156                                          tmp);
 157                if (ret < 0) {
 158                        debug("%s: Error in checksum calculation\n", __func__);
 159                        goto out;
 160                }
 161
 162                i = 0;
 163                while ((i_output < output_len) && (i < hash_len)) {
 164                        output[i_output] = tmp[i];
 165                        i_output++;
 166                        i++;
 167                }
 168
 169                counter++;
 170        }
 171
 172out:
 173        free(tmp);
 174
 175        return ret;
 176}
 177
 178static int compute_hash_prime(struct checksum_algo *checksum,
 179                              uint8_t *pad, int pad_len,
 180                              uint8_t *hash, int hash_len,
 181                              uint8_t *salt, int salt_len,
 182                              uint8_t *hprime)
 183{
 184        struct image_region region[3];
 185        int ret, region_count = 3;
 186
 187        region[0].data = pad;
 188        region[0].size = pad_len;
 189        region[1].data = hash;
 190        region[1].size = hash_len;
 191        region[2].data = salt;
 192        region[2].size = salt_len;
 193
 194        ret = checksum->calculate(checksum->name, region, region_count, hprime);
 195        if (ret < 0) {
 196                debug("%s: Error in checksum calculation\n", __func__);
 197                goto out;
 198        }
 199
 200out:
 201        return ret;
 202}
 203
 204/*
 205 * padding_pss_verify() - verify the pss padding of a signature
 206 *
 207 * Only works with a rsa_pss_saltlen:-2 (default value) right now
 208 * saltlen:-1 "set the salt length to the digest length" is currently
 209 * not supported.
 210 *
 211 * @info:       Specifies key and FIT information
 212 * @msg:        byte array of message, len equal to msg_len
 213 * @msg_len:    Message length
 214 * @hash:       Pointer to the expected hash
 215 * @hash_len:   Length of the hash
 216 */
 217int padding_pss_verify(struct image_sign_info *info,
 218                       uint8_t *msg, int msg_len,
 219                       const uint8_t *hash, int hash_len)
 220{
 221        uint8_t *masked_db = NULL;
 222        int masked_db_len = msg_len - hash_len - 1;
 223        uint8_t *h = NULL, *hprime = NULL;
 224        int h_len = hash_len;
 225        uint8_t *db_mask = NULL;
 226        int db_mask_len = masked_db_len;
 227        uint8_t *db = NULL, *salt = NULL;
 228        int db_len = masked_db_len, salt_len = msg_len - hash_len - 2;
 229        uint8_t pad_zero[8] = { 0 };
 230        int ret, i, leftmost_bits = 1;
 231        uint8_t leftmost_mask;
 232        struct checksum_algo *checksum = info->checksum;
 233
 234        /* first, allocate everything */
 235        masked_db = malloc(masked_db_len);
 236        h = malloc(h_len);
 237        db_mask = malloc(db_mask_len);
 238        db = malloc(db_len);
 239        salt = malloc(salt_len);
 240        hprime = malloc(hash_len);
 241        if (!masked_db || !h || !db_mask || !db || !salt || !hprime) {
 242                printf("%s: can't allocate some buffer\n", __func__);
 243                ret = -ENOMEM;
 244                goto out;
 245        }
 246
 247        /* step 4: check if the last byte is 0xbc */
 248        if (msg[msg_len - 1] != 0xbc) {
 249                printf("%s: invalid pss padding (0xbc is missing)\n", __func__);
 250                ret = -EINVAL;
 251                goto out;
 252        }
 253
 254        /* step 5 */
 255        memcpy(masked_db, msg, masked_db_len);
 256        memcpy(h, msg + masked_db_len, h_len);
 257
 258        /* step 6 */
 259        leftmost_mask = (0xff >> (8 - leftmost_bits)) << (8 - leftmost_bits);
 260        if (masked_db[0] & leftmost_mask) {
 261                printf("%s: invalid pss padding ", __func__);
 262                printf("(leftmost bit of maskedDB not zero)\n");
 263                ret = -EINVAL;
 264                goto out;
 265        }
 266
 267        /* step 7 */
 268        mask_generation_function1(checksum, h, h_len, db_mask, db_mask_len);
 269
 270        /* step 8 */
 271        for (i = 0; i < db_len; i++)
 272                db[i] = masked_db[i] ^ db_mask[i];
 273
 274        /* step 9 */
 275        db[0] &= 0xff >> leftmost_bits;
 276
 277        /* step 10 */
 278        if (db[0] != 0x01) {
 279                printf("%s: invalid pss padding ", __func__);
 280                printf("(leftmost byte of db isn't 0x01)\n");
 281                ret = EINVAL;
 282                goto out;
 283        }
 284
 285        /* step 11 */
 286        memcpy(salt, &db[1], salt_len);
 287
 288        /* step 12 & 13 */
 289        compute_hash_prime(checksum, pad_zero, 8,
 290                           (uint8_t *)hash, hash_len,
 291                           salt, salt_len, hprime);
 292
 293        /* step 14 */
 294        ret = memcmp(h, hprime, hash_len);
 295
 296out:
 297        free(hprime);
 298        free(salt);
 299        free(db);
 300        free(db_mask);
 301        free(h);
 302        free(masked_db);
 303
 304        return ret;
 305}
 306
 307#ifndef USE_HOSTCC
 308U_BOOT_PADDING_ALGO(pss) = {
 309        .name = "pss",
 310        .verify = padding_pss_verify,
 311};
 312#endif
 313
 314#endif
 315
 316/**
 317 * rsa_verify_key() - Verify a signature against some data using RSA Key
 318 *
 319 * Verify a RSA PKCS1.5 signature against an expected hash using
 320 * the RSA Key properties in prop structure.
 321 *
 322 * @info:       Specifies key and FIT information
 323 * @prop:       Specifies key
 324 * @sig:        Signature
 325 * @sig_len:    Number of bytes in signature
 326 * @hash:       Pointer to the expected hash
 327 * @key_len:    Number of bytes in rsa key
 328 * @return 0 if verified, -ve on error
 329 */
 330static int rsa_verify_key(struct image_sign_info *info,
 331                          struct key_prop *prop, const uint8_t *sig,
 332                          const uint32_t sig_len, const uint8_t *hash,
 333                          const uint32_t key_len)
 334{
 335        int ret;
 336#if !defined(USE_HOSTCC)
 337        struct udevice *mod_exp_dev;
 338#endif
 339        struct checksum_algo *checksum = info->checksum;
 340        struct padding_algo *padding = info->padding;
 341        int hash_len;
 342
 343        if (!prop || !sig || !hash || !checksum || !padding)
 344                return -EIO;
 345
 346        if (sig_len != (prop->num_bits / 8)) {
 347                debug("Signature is of incorrect length %d\n", sig_len);
 348                return -EINVAL;
 349        }
 350
 351        debug("Checksum algorithm: %s", checksum->name);
 352
 353        /* Sanity check for stack size */
 354        if (sig_len > RSA_MAX_SIG_BITS / 8) {
 355                debug("Signature length %u exceeds maximum %d\n", sig_len,
 356                      RSA_MAX_SIG_BITS / 8);
 357                return -EINVAL;
 358        }
 359
 360        uint8_t buf[sig_len];
 361        hash_len = checksum->checksum_len;
 362
 363#if !defined(USE_HOSTCC)
 364        ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
 365        if (ret) {
 366                printf("RSA: Can't find Modular Exp implementation\n");
 367                return -EINVAL;
 368        }
 369
 370        ret = rsa_mod_exp(mod_exp_dev, sig, sig_len, prop, buf);
 371#else
 372        ret = rsa_mod_exp_sw(sig, sig_len, prop, buf);
 373#endif
 374        if (ret) {
 375                debug("Error in Modular exponentation\n");
 376                return ret;
 377        }
 378
 379        ret = padding->verify(info, buf, key_len, hash, hash_len);
 380        if (ret) {
 381                debug("In RSAVerify(): padding check failed!\n");
 382                return ret;
 383        }
 384
 385        return 0;
 386}
 387
 388/**
 389 * rsa_verify_with_pkey() - Verify a signature against some data using
 390 * only modulus and exponent as RSA key properties.
 391 * @info:       Specifies key information
 392 * @hash:       Pointer to the expected hash
 393 * @sig:        Signature
 394 * @sig_len:    Number of bytes in signature
 395 *
 396 * Parse a RSA public key blob in DER format pointed to in @info and fill
 397 * a key_prop structure with properties of the key. Then verify a RSA PKCS1.5
 398 * signature against an expected hash using the calculated properties.
 399 *
 400 * Return       0 if verified, -ve on error
 401 */
 402int rsa_verify_with_pkey(struct image_sign_info *info,
 403                         const void *hash, uint8_t *sig, uint sig_len)
 404{
 405        struct key_prop *prop;
 406        int ret;
 407
 408        if (!CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY))
 409                return -EACCES;
 410
 411        /* Public key is self-described to fill key_prop */
 412        ret = rsa_gen_key_prop(info->key, info->keylen, &prop);
 413        if (ret) {
 414                debug("Generating necessary parameter for decoding failed\n");
 415                return ret;
 416        }
 417
 418        ret = rsa_verify_key(info, prop, sig, sig_len, hash,
 419                             info->crypto->key_len);
 420
 421        rsa_free_key_prop(prop);
 422
 423        return ret;
 424}
 425
 426#if CONFIG_IS_ENABLED(FIT_SIGNATURE)
 427/**
 428 * rsa_verify_with_keynode() - Verify a signature against some data using
 429 * information in node with prperties of RSA Key like modulus, exponent etc.
 430 *
 431 * Parse sign-node and fill a key_prop structure with properties of the
 432 * key.  Verify a RSA PKCS1.5 signature against an expected hash using
 433 * the properties parsed
 434 *
 435 * @info:       Specifies key and FIT information
 436 * @hash:       Pointer to the expected hash
 437 * @sig:        Signature
 438 * @sig_len:    Number of bytes in signature
 439 * @node:       Node having the RSA Key properties
 440 * @return 0 if verified, -ve on error
 441 */
 442static int rsa_verify_with_keynode(struct image_sign_info *info,
 443                                   const void *hash, uint8_t *sig,
 444                                   uint sig_len, int node)
 445{
 446        const void *blob = info->fdt_blob;
 447        struct key_prop prop;
 448        int length;
 449        int ret = 0;
 450        const char *algo;
 451
 452        if (node < 0) {
 453                debug("%s: Skipping invalid node", __func__);
 454                return -EBADF;
 455        }
 456
 457        algo = fdt_getprop(blob, node, "algo", NULL);
 458        if (strcmp(info->name, algo)) {
 459                debug("%s: Wrong algo: have %s, expected %s", __func__,
 460                      info->name, algo);
 461                return -EFAULT;
 462        }
 463
 464        prop.num_bits = fdtdec_get_int(blob, node, "rsa,num-bits", 0);
 465
 466        prop.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0);
 467
 468        prop.public_exponent = fdt_getprop(blob, node, "rsa,exponent", &length);
 469        if (!prop.public_exponent || length < sizeof(uint64_t))
 470                prop.public_exponent = NULL;
 471
 472        prop.exp_len = sizeof(uint64_t);
 473
 474        prop.modulus = fdt_getprop(blob, node, "rsa,modulus", NULL);
 475
 476        prop.rr = fdt_getprop(blob, node, "rsa,r-squared", NULL);
 477
 478        if (!prop.num_bits || !prop.modulus || !prop.rr) {
 479                debug("%s: Missing RSA key info", __func__);
 480                return -EFAULT;
 481        }
 482
 483        ret = rsa_verify_key(info, &prop, sig, sig_len, hash,
 484                             info->crypto->key_len);
 485
 486        return ret;
 487}
 488#else
 489static int rsa_verify_with_keynode(struct image_sign_info *info,
 490                                   const void *hash, uint8_t *sig,
 491                                   uint sig_len, int node)
 492{
 493        return -EACCES;
 494}
 495#endif
 496
 497int rsa_verify_hash(struct image_sign_info *info,
 498                    const uint8_t *hash, uint8_t *sig, uint sig_len)
 499{
 500        int ret = -EACCES;
 501
 502        if (CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY) && !info->fdt_blob) {
 503                /* don't rely on fdt properties */
 504                ret = rsa_verify_with_pkey(info, hash, sig, sig_len);
 505
 506                return ret;
 507        }
 508
 509        if (CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
 510                const void *blob = info->fdt_blob;
 511                int ndepth, noffset;
 512                int sig_node, node;
 513                char name[100];
 514
 515                sig_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME);
 516                if (sig_node < 0) {
 517                        debug("%s: No signature node found\n", __func__);
 518                        return -ENOENT;
 519                }
 520
 521                /* See if we must use a particular key */
 522                if (info->required_keynode != -1) {
 523                        ret = rsa_verify_with_keynode(info, hash, sig, sig_len,
 524                                                      info->required_keynode);
 525                        return ret;
 526                }
 527
 528                /* Look for a key that matches our hint */
 529                snprintf(name, sizeof(name), "key-%s", info->keyname);
 530                node = fdt_subnode_offset(blob, sig_node, name);
 531                ret = rsa_verify_with_keynode(info, hash, sig, sig_len, node);
 532                if (!ret)
 533                        return ret;
 534
 535                /* No luck, so try each of the keys in turn */
 536                for (ndepth = 0, noffset = fdt_next_node(blob, sig_node,
 537                                                         &ndepth);
 538                     (noffset >= 0) && (ndepth > 0);
 539                     noffset = fdt_next_node(blob, noffset, &ndepth)) {
 540                        if (ndepth == 1 && noffset != node) {
 541                                ret = rsa_verify_with_keynode(info, hash,
 542                                                              sig, sig_len,
 543                                                              noffset);
 544                                if (!ret)
 545                                        break;
 546                        }
 547                }
 548        }
 549
 550        return ret;
 551}
 552
 553int rsa_verify(struct image_sign_info *info,
 554               const struct image_region region[], int region_count,
 555               uint8_t *sig, uint sig_len)
 556{
 557        /* Reserve memory for maximum checksum-length */
 558        uint8_t hash[info->crypto->key_len];
 559        int ret;
 560
 561        /*
 562         * Verify that the checksum-length does not exceed the
 563         * rsa-signature-length
 564         */
 565        if (info->checksum->checksum_len >
 566            info->crypto->key_len) {
 567                debug("%s: invalid checksum-algorithm %s for %s\n",
 568                      __func__, info->checksum->name, info->crypto->name);
 569                return -EINVAL;
 570        }
 571
 572        /* Calculate checksum with checksum-algorithm */
 573        ret = info->checksum->calculate(info->checksum->name,
 574                                        region, region_count, hash);
 575        if (ret < 0) {
 576                debug("%s: Error in checksum calculation\n", __func__);
 577                return -EINVAL;
 578        }
 579
 580        return rsa_verify_hash(info, hash, sig, sig_len);
 581}
 582
 583#ifndef USE_HOSTCC
 584
 585U_BOOT_CRYPTO_ALGO(rsa2048) = {
 586        .name = "rsa2048",
 587        .key_len = RSA2048_BYTES,
 588        .verify = rsa_verify,
 589};
 590
 591U_BOOT_CRYPTO_ALGO(rsa4096) = {
 592        .name = "rsa4096",
 593        .key_len = RSA4096_BYTES,
 594        .verify = rsa_verify,
 595};
 596
 597#endif
 598