uboot/lib/rsa/rsa-sign.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2013, Google Inc.
   4 */
   5
   6#define OPENSSL_API_COMPAT 0x10101000L
   7
   8#include "mkimage.h"
   9#include <stdlib.h>
  10#include <stdio.h>
  11#include <string.h>
  12#include <image.h>
  13#include <time.h>
  14#include <u-boot/fdt-libcrypto.h>
  15#include <openssl/bn.h>
  16#include <openssl/ec.h>
  17#include <openssl/rsa.h>
  18#include <openssl/pem.h>
  19#include <openssl/err.h>
  20#include <openssl/ssl.h>
  21#include <openssl/evp.h>
  22#include <openssl/engine.h>
  23
  24static int rsa_err(const char *msg)
  25{
  26        unsigned long sslErr = ERR_get_error();
  27
  28        fprintf(stderr, "%s", msg);
  29        fprintf(stderr, ": %s\n",
  30                ERR_error_string(sslErr, 0));
  31
  32        return -1;
  33}
  34
  35/**
  36 * rsa_pem_get_pub_key() - read a public key from a .crt file
  37 *
  38 * @keydir:     Directory containins the key
  39 * @name        Name of key file (will have a .crt extension)
  40 * @evpp        Returns EVP_PKEY object, or NULL on failure
  41 * @return 0 if ok, -ve on error (in which case *evpp will be set to NULL)
  42 */
  43static int rsa_pem_get_pub_key(const char *keydir, const char *name, EVP_PKEY **evpp)
  44{
  45        char path[1024];
  46        EVP_PKEY *key = NULL;
  47        X509 *cert;
  48        FILE *f;
  49        int ret;
  50
  51        if (!evpp)
  52                return -EINVAL;
  53
  54        *evpp = NULL;
  55        snprintf(path, sizeof(path), "%s/%s.crt", keydir, name);
  56        f = fopen(path, "r");
  57        if (!f) {
  58                fprintf(stderr, "Couldn't open RSA certificate: '%s': %s\n",
  59                        path, strerror(errno));
  60                return -EACCES;
  61        }
  62
  63        /* Read the certificate */
  64        cert = NULL;
  65        if (!PEM_read_X509(f, &cert, NULL, NULL)) {
  66                rsa_err("Couldn't read certificate");
  67                ret = -EINVAL;
  68                goto err_cert;
  69        }
  70
  71        /* Get the public key from the certificate. */
  72        key = X509_get_pubkey(cert);
  73        if (!key) {
  74                rsa_err("Couldn't read public key\n");
  75                ret = -EINVAL;
  76                goto err_pubkey;
  77        }
  78
  79        fclose(f);
  80        *evpp = key;
  81        X509_free(cert);
  82
  83        return 0;
  84
  85err_pubkey:
  86        X509_free(cert);
  87err_cert:
  88        fclose(f);
  89        return ret;
  90}
  91
  92/**
  93 * rsa_engine_get_pub_key() - read a public key from given engine
  94 *
  95 * @keydir:     Key prefix
  96 * @name        Name of key
  97 * @engine      Engine to use
  98 * @evpp        Returns EVP_PKEY object, or NULL on failure
  99 * @return 0 if ok, -ve on error (in which case *evpp will be set to NULL)
 100 */
 101static int rsa_engine_get_pub_key(const char *keydir, const char *name,
 102                                  ENGINE *engine, EVP_PKEY **evpp)
 103{
 104        const char *engine_id;
 105        char key_id[1024];
 106        EVP_PKEY *key = NULL;
 107
 108        if (!evpp)
 109                return -EINVAL;
 110
 111        *evpp = NULL;
 112
 113        engine_id = ENGINE_get_id(engine);
 114
 115        if (engine_id && !strcmp(engine_id, "pkcs11")) {
 116                if (keydir)
 117                        if (strstr(keydir, "object="))
 118                                snprintf(key_id, sizeof(key_id),
 119                                         "pkcs11:%s;type=public",
 120                                         keydir);
 121                        else
 122                                snprintf(key_id, sizeof(key_id),
 123                                         "pkcs11:%s;object=%s;type=public",
 124                                         keydir, name);
 125                else
 126                        snprintf(key_id, sizeof(key_id),
 127                                 "pkcs11:object=%s;type=public",
 128                                 name);
 129        } else if (engine_id) {
 130                if (keydir)
 131                        snprintf(key_id, sizeof(key_id),
 132                                 "%s%s",
 133                                 keydir, name);
 134                else
 135                        snprintf(key_id, sizeof(key_id),
 136                                 "%s",
 137                                 name);
 138        } else {
 139                fprintf(stderr, "Engine not supported\n");
 140                return -ENOTSUP;
 141        }
 142
 143        key = ENGINE_load_public_key(engine, key_id, NULL, NULL);
 144        if (!key)
 145                return rsa_err("Failure loading public key from engine");
 146
 147        *evpp = key;
 148
 149        return 0;
 150}
 151
 152/**
 153 * rsa_get_pub_key() - read a public key
 154 *
 155 * @keydir:     Directory containing the key (PEM file) or key prefix (engine)
 156 * @name        Name of key file (will have a .crt extension)
 157 * @engine      Engine to use
 158 * @evpp        Returns EVP_PKEY object, or NULL on failure
 159 * @return 0 if ok, -ve on error (in which case *evpp will be set to NULL)
 160 */
 161static int rsa_get_pub_key(const char *keydir, const char *name,
 162                           ENGINE *engine, EVP_PKEY **evpp)
 163{
 164        if (engine)
 165                return rsa_engine_get_pub_key(keydir, name, engine, evpp);
 166        return rsa_pem_get_pub_key(keydir, name, evpp);
 167}
 168
 169/**
 170 * rsa_pem_get_priv_key() - read a private key from a .key file
 171 *
 172 * @keydir:     Directory containing the key
 173 * @name        Name of key file (will have a .key extension)
 174 * @evpp        Returns EVP_PKEY object, or NULL on failure
 175 * @return 0 if ok, -ve on error (in which case *evpp will be set to NULL)
 176 */
 177static int rsa_pem_get_priv_key(const char *keydir, const char *name,
 178                                const char *keyfile, EVP_PKEY **evpp)
 179{
 180        char path[1024] = {0};
 181        FILE *f = NULL;
 182
 183        if (!evpp)
 184                return -EINVAL;
 185
 186        *evpp = NULL;
 187        if (keydir && name)
 188                snprintf(path, sizeof(path), "%s/%s.key", keydir, name);
 189        else if (keyfile)
 190                snprintf(path, sizeof(path), "%s", keyfile);
 191        else
 192                return -EINVAL;
 193
 194        f = fopen(path, "r");
 195        if (!f) {
 196                fprintf(stderr, "Couldn't open RSA private key: '%s': %s\n",
 197                        path, strerror(errno));
 198                return -ENOENT;
 199        }
 200
 201        if (!PEM_read_PrivateKey(f, evpp, NULL, path)) {
 202                rsa_err("Failure reading private key");
 203                fclose(f);
 204                return -EPROTO;
 205        }
 206        fclose(f);
 207
 208        return 0;
 209}
 210
 211/**
 212 * rsa_engine_get_priv_key() - read a private key from given engine
 213 *
 214 * @keydir:     Key prefix
 215 * @name        Name of key
 216 * @engine      Engine to use
 217 * @evpp        Returns EVP_PKEY object, or NULL on failure
 218 * @return 0 if ok, -ve on error (in which case *evpp will be set to NULL)
 219 */
 220static int rsa_engine_get_priv_key(const char *keydir, const char *name,
 221                                   const char *keyfile,
 222                                   ENGINE *engine, EVP_PKEY **evpp)
 223{
 224        const char *engine_id;
 225        char key_id[1024];
 226        EVP_PKEY *key = NULL;
 227
 228        if (!evpp)
 229                return -EINVAL;
 230
 231        engine_id = ENGINE_get_id(engine);
 232
 233        if (engine_id && !strcmp(engine_id, "pkcs11")) {
 234                if (!keydir && !name) {
 235                        fprintf(stderr, "Please use 'keydir' with PKCS11\n");
 236                        return -EINVAL;
 237                }
 238                if (keydir)
 239                        if (strstr(keydir, "object="))
 240                                snprintf(key_id, sizeof(key_id),
 241                                         "pkcs11:%s;type=private",
 242                                         keydir);
 243                        else
 244                                snprintf(key_id, sizeof(key_id),
 245                                         "pkcs11:%s;object=%s;type=private",
 246                                         keydir, name);
 247                else
 248                        snprintf(key_id, sizeof(key_id),
 249                                 "pkcs11:object=%s;type=private",
 250                                 name);
 251        } else if (engine_id) {
 252                if (keydir && name)
 253                        snprintf(key_id, sizeof(key_id),
 254                                 "%s%s",
 255                                 keydir, name);
 256                else if (name)
 257                        snprintf(key_id, sizeof(key_id),
 258                                 "%s",
 259                                 name ? name : "");
 260                else if (keyfile)
 261                        snprintf(key_id, sizeof(key_id), "%s", keyfile);
 262                else
 263                        return -EINVAL;
 264
 265        } else {
 266                fprintf(stderr, "Engine not supported\n");
 267                return -ENOTSUP;
 268        }
 269
 270        key = ENGINE_load_private_key(engine, key_id, NULL, NULL);
 271        if (!key)
 272                return rsa_err("Failure loading private key from engine");
 273
 274        *evpp = key;
 275
 276        return 0;
 277}
 278
 279/**
 280 * rsa_get_priv_key() - read a private key
 281 *
 282 * @keydir:     Directory containing the key (PEM file) or key prefix (engine)
 283 * @name        Name of key
 284 * @engine      Engine to use for signing
 285 * @evpp        Returns EVP_PKEY object, or NULL on failure
 286 * @return 0 if ok, -ve on error (in which case *evpp will be set to NULL)
 287 */
 288static int rsa_get_priv_key(const char *keydir, const char *name,
 289                            const char *keyfile, ENGINE *engine, EVP_PKEY **evpp)
 290{
 291        if (engine)
 292                return rsa_engine_get_priv_key(keydir, name, keyfile, engine,
 293                                               evpp);
 294        return rsa_pem_get_priv_key(keydir, name, keyfile, evpp);
 295}
 296
 297static int rsa_init(void)
 298{
 299        int ret;
 300
 301        ret = OPENSSL_init_ssl(0, NULL);
 302        if (!ret) {
 303                fprintf(stderr, "Failure to init SSL library\n");
 304                return -1;
 305        }
 306
 307        return 0;
 308}
 309
 310static int rsa_engine_init(const char *engine_id, ENGINE **pe)
 311{
 312        const char *key_pass;
 313        ENGINE *e;
 314        int ret;
 315
 316        ENGINE_load_builtin_engines();
 317
 318        e = ENGINE_by_id(engine_id);
 319        if (!e) {
 320                fprintf(stderr, "Engine isn't available\n");
 321                return -1;
 322        }
 323
 324        if (!ENGINE_init(e)) {
 325                fprintf(stderr, "Couldn't initialize engine\n");
 326                ret = -1;
 327                goto err_engine_init;
 328        }
 329
 330        if (!ENGINE_set_default_RSA(e)) {
 331                fprintf(stderr, "Couldn't set engine as default for RSA\n");
 332                ret = -1;
 333                goto err_set_rsa;
 334        }
 335
 336        key_pass = getenv("MKIMAGE_SIGN_PIN");
 337        if (key_pass) {
 338                if (!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) {
 339                        fprintf(stderr, "Couldn't set PIN\n");
 340                        ret = -1;
 341                        goto err_set_pin;
 342                }
 343        }
 344
 345        *pe = e;
 346
 347        return 0;
 348
 349err_set_pin:
 350err_set_rsa:
 351        ENGINE_finish(e);
 352err_engine_init:
 353        ENGINE_free(e);
 354        return ret;
 355}
 356
 357static void rsa_engine_remove(ENGINE *e)
 358{
 359        if (e) {
 360                ENGINE_finish(e);
 361                ENGINE_free(e);
 362        }
 363}
 364
 365static int rsa_sign_with_key(EVP_PKEY *pkey, struct padding_algo *padding_algo,
 366                             struct checksum_algo *checksum_algo,
 367                const struct image_region region[], int region_count,
 368                uint8_t **sigp, uint *sig_size)
 369{
 370        EVP_PKEY_CTX *ckey;
 371        EVP_MD_CTX *context;
 372        int ret = 0;
 373        size_t size;
 374        uint8_t *sig;
 375        int i;
 376
 377        size = EVP_PKEY_size(pkey);
 378        sig = malloc(size);
 379        if (!sig) {
 380                fprintf(stderr, "Out of memory for signature (%zu bytes)\n",
 381                        size);
 382                ret = -ENOMEM;
 383                goto err_alloc;
 384        }
 385
 386        context = EVP_MD_CTX_create();
 387        if (!context) {
 388                ret = rsa_err("EVP context creation failed");
 389                goto err_create;
 390        }
 391        EVP_MD_CTX_init(context);
 392
 393        ckey = EVP_PKEY_CTX_new(pkey, NULL);
 394        if (!ckey) {
 395                ret = rsa_err("EVP key context creation failed");
 396                goto err_create;
 397        }
 398
 399        if (EVP_DigestSignInit(context, &ckey,
 400                               checksum_algo->calculate_sign(),
 401                               NULL, pkey) <= 0) {
 402                ret = rsa_err("Signer setup failed");
 403                goto err_sign;
 404        }
 405
 406        if (CONFIG_IS_ENABLED(FIT_RSASSA_PSS) && padding_algo &&
 407            !strcmp(padding_algo->name, "pss")) {
 408                if (EVP_PKEY_CTX_set_rsa_padding(ckey,
 409                                                 RSA_PKCS1_PSS_PADDING) <= 0) {
 410                        ret = rsa_err("Signer padding setup failed");
 411                        goto err_sign;
 412                }
 413        }
 414
 415        for (i = 0; i < region_count; i++) {
 416                if (!EVP_DigestSignUpdate(context, region[i].data,
 417                                          region[i].size)) {
 418                        ret = rsa_err("Signing data failed");
 419                        goto err_sign;
 420                }
 421        }
 422
 423        if (!EVP_DigestSignFinal(context, sig, &size)) {
 424                ret = rsa_err("Could not obtain signature");
 425                goto err_sign;
 426        }
 427
 428        EVP_MD_CTX_reset(context);
 429        EVP_MD_CTX_destroy(context);
 430
 431        debug("Got signature: %zu bytes, expected %d\n", size, EVP_PKEY_size(pkey));
 432        *sigp = sig;
 433        *sig_size = size;
 434
 435        return 0;
 436
 437err_sign:
 438        EVP_MD_CTX_destroy(context);
 439err_create:
 440        free(sig);
 441err_alloc:
 442        return ret;
 443}
 444
 445int rsa_sign(struct image_sign_info *info,
 446             const struct image_region region[], int region_count,
 447             uint8_t **sigp, uint *sig_len)
 448{
 449        EVP_PKEY *pkey = NULL;
 450        ENGINE *e = NULL;
 451        int ret;
 452
 453        ret = rsa_init();
 454        if (ret)
 455                return ret;
 456
 457        if (info->engine_id) {
 458                ret = rsa_engine_init(info->engine_id, &e);
 459                if (ret)
 460                        return ret;
 461        }
 462
 463        ret = rsa_get_priv_key(info->keydir, info->keyname, info->keyfile,
 464                               e, &pkey);
 465        if (ret)
 466                goto err_priv;
 467        ret = rsa_sign_with_key(pkey, info->padding, info->checksum, region,
 468                                region_count, sigp, sig_len);
 469        if (ret)
 470                goto err_sign;
 471
 472        EVP_PKEY_free(pkey);
 473        if (info->engine_id)
 474                rsa_engine_remove(e);
 475
 476        return ret;
 477
 478err_sign:
 479        EVP_PKEY_free(pkey);
 480err_priv:
 481        if (info->engine_id)
 482                rsa_engine_remove(e);
 483        return ret;
 484}
 485
 486/*
 487 * rsa_get_exponent(): - Get the public exponent from an RSA key
 488 */
 489static int rsa_get_exponent(RSA *key, uint64_t *e)
 490{
 491        int ret;
 492        BIGNUM *bn_te;
 493        const BIGNUM *key_e;
 494        uint64_t te;
 495
 496        ret = -EINVAL;
 497        bn_te = NULL;
 498
 499        if (!e)
 500                goto cleanup;
 501
 502        RSA_get0_key(key, NULL, &key_e, NULL);
 503        if (BN_num_bits(key_e) > 64)
 504                goto cleanup;
 505
 506        *e = BN_get_word(key_e);
 507
 508        if (BN_num_bits(key_e) < 33) {
 509                ret = 0;
 510                goto cleanup;
 511        }
 512
 513        bn_te = BN_dup(key_e);
 514        if (!bn_te)
 515                goto cleanup;
 516
 517        if (!BN_rshift(bn_te, bn_te, 32))
 518                goto cleanup;
 519
 520        if (!BN_mask_bits(bn_te, 32))
 521                goto cleanup;
 522
 523        te = BN_get_word(bn_te);
 524        te <<= 32;
 525        *e |= te;
 526        ret = 0;
 527
 528cleanup:
 529        if (bn_te)
 530                BN_free(bn_te);
 531
 532        return ret;
 533}
 534
 535/*
 536 * rsa_get_params(): - Get the important parameters of an RSA public key
 537 */
 538int rsa_get_params(RSA *key, uint64_t *exponent, uint32_t *n0_invp,
 539                   BIGNUM **modulusp, BIGNUM **r_squaredp)
 540{
 541        BIGNUM *big1, *big2, *big32, *big2_32;
 542        BIGNUM *n, *r, *r_squared, *tmp;
 543        const BIGNUM *key_n;
 544        BN_CTX *bn_ctx = BN_CTX_new();
 545        int ret = 0;
 546
 547        /* Initialize BIGNUMs */
 548        big1 = BN_new();
 549        big2 = BN_new();
 550        big32 = BN_new();
 551        r = BN_new();
 552        r_squared = BN_new();
 553        tmp = BN_new();
 554        big2_32 = BN_new();
 555        n = BN_new();
 556        if (!big1 || !big2 || !big32 || !r || !r_squared || !tmp || !big2_32 ||
 557            !n) {
 558                fprintf(stderr, "Out of memory (bignum)\n");
 559                return -ENOMEM;
 560        }
 561
 562        if (0 != rsa_get_exponent(key, exponent))
 563                ret = -1;
 564
 565        RSA_get0_key(key, &key_n, NULL, NULL);
 566        if (!BN_copy(n, key_n) || !BN_set_word(big1, 1L) ||
 567            !BN_set_word(big2, 2L) || !BN_set_word(big32, 32L))
 568                ret = -1;
 569
 570        /* big2_32 = 2^32 */
 571        if (!BN_exp(big2_32, big2, big32, bn_ctx))
 572                ret = -1;
 573
 574        /* Calculate n0_inv = -1 / n[0] mod 2^32 */
 575        if (!BN_mod_inverse(tmp, n, big2_32, bn_ctx) ||
 576            !BN_sub(tmp, big2_32, tmp))
 577                ret = -1;
 578        *n0_invp = BN_get_word(tmp);
 579
 580        /* Calculate R = 2^(# of key bits) */
 581        if (!BN_set_word(tmp, BN_num_bits(n)) ||
 582            !BN_exp(r, big2, tmp, bn_ctx))
 583                ret = -1;
 584
 585        /* Calculate r_squared = R^2 mod n */
 586        if (!BN_copy(r_squared, r) ||
 587            !BN_mul(tmp, r_squared, r, bn_ctx) ||
 588            !BN_mod(r_squared, tmp, n, bn_ctx))
 589                ret = -1;
 590
 591        *modulusp = n;
 592        *r_squaredp = r_squared;
 593
 594        BN_free(big1);
 595        BN_free(big2);
 596        BN_free(big32);
 597        BN_free(r);
 598        BN_free(tmp);
 599        BN_free(big2_32);
 600        if (ret) {
 601                fprintf(stderr, "Bignum operations failed\n");
 602                return -ENOMEM;
 603        }
 604
 605        return ret;
 606}
 607
 608int rsa_add_verify_data(struct image_sign_info *info, void *keydest)
 609{
 610        BIGNUM *modulus, *r_squared;
 611        uint64_t exponent;
 612        uint32_t n0_inv;
 613        int parent, node;
 614        char name[100];
 615        int ret;
 616        int bits;
 617        RSA *rsa;
 618        EVP_PKEY *pkey = NULL;
 619        ENGINE *e = NULL;
 620
 621        debug("%s: Getting verification data\n", __func__);
 622        if (info->engine_id) {
 623                ret = rsa_engine_init(info->engine_id, &e);
 624                if (ret)
 625                        return ret;
 626        }
 627        ret = rsa_get_pub_key(info->keydir, info->keyname, e, &pkey);
 628        if (ret)
 629                goto err_get_pub_key;
 630
 631        rsa = (RSA *)EVP_PKEY_get0_RSA(pkey);
 632        ret = rsa_get_params(rsa, &exponent, &n0_inv, &modulus, &r_squared);
 633        if (ret)
 634                goto err_get_params;
 635        bits = BN_num_bits(modulus);
 636        parent = fdt_subnode_offset(keydest, 0, FIT_SIG_NODENAME);
 637        if (parent == -FDT_ERR_NOTFOUND) {
 638                parent = fdt_add_subnode(keydest, 0, FIT_SIG_NODENAME);
 639                if (parent < 0) {
 640                        ret = parent;
 641                        if (ret != -FDT_ERR_NOSPACE) {
 642                                fprintf(stderr, "Couldn't create signature node: %s\n",
 643                                        fdt_strerror(parent));
 644                        }
 645                }
 646        }
 647        if (ret)
 648                goto done;
 649
 650        /* Either create or overwrite the named key node */
 651        snprintf(name, sizeof(name), "key-%s", info->keyname);
 652        node = fdt_subnode_offset(keydest, parent, name);
 653        if (node == -FDT_ERR_NOTFOUND) {
 654                node = fdt_add_subnode(keydest, parent, name);
 655                if (node < 0) {
 656                        ret = node;
 657                        if (ret != -FDT_ERR_NOSPACE) {
 658                                fprintf(stderr, "Could not create key subnode: %s\n",
 659                                        fdt_strerror(node));
 660                        }
 661                }
 662        } else if (node < 0) {
 663                fprintf(stderr, "Cannot select keys parent: %s\n",
 664                        fdt_strerror(node));
 665                ret = node;
 666        }
 667
 668        if (!ret) {
 669                ret = fdt_setprop_string(keydest, node, FIT_KEY_HINT,
 670                                         info->keyname);
 671        }
 672        if (!ret)
 673                ret = fdt_setprop_u32(keydest, node, "rsa,num-bits", bits);
 674        if (!ret)
 675                ret = fdt_setprop_u32(keydest, node, "rsa,n0-inverse", n0_inv);
 676        if (!ret) {
 677                ret = fdt_setprop_u64(keydest, node, "rsa,exponent", exponent);
 678        }
 679        if (!ret) {
 680                ret = fdt_add_bignum(keydest, node, "rsa,modulus", modulus,
 681                                     bits);
 682        }
 683        if (!ret) {
 684                ret = fdt_add_bignum(keydest, node, "rsa,r-squared", r_squared,
 685                                     bits);
 686        }
 687        if (!ret) {
 688                ret = fdt_setprop_string(keydest, node, FIT_ALGO_PROP,
 689                                         info->name);
 690        }
 691        if (!ret && info->require_keys) {
 692                ret = fdt_setprop_string(keydest, node, FIT_KEY_REQUIRED,
 693                                         info->require_keys);
 694        }
 695done:
 696        BN_free(modulus);
 697        BN_free(r_squared);
 698        if (ret)
 699                ret = ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
 700err_get_params:
 701        EVP_PKEY_free(pkey);
 702err_get_pub_key:
 703        if (info->engine_id)
 704                rsa_engine_remove(e);
 705
 706        return ret;
 707}
 708