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_new();
 387        if (!context) {
 388                ret = rsa_err("EVP context creation failed");
 389                goto err_create;
 390        }
 391
 392        ckey = EVP_PKEY_CTX_new(pkey, NULL);
 393        if (!ckey) {
 394                ret = rsa_err("EVP key context creation failed");
 395                goto err_create;
 396        }
 397
 398        if (EVP_DigestSignInit(context, &ckey,
 399                               checksum_algo->calculate_sign(),
 400                               NULL, pkey) <= 0) {
 401                ret = rsa_err("Signer setup failed");
 402                goto err_sign;
 403        }
 404
 405        if (CONFIG_IS_ENABLED(FIT_RSASSA_PSS) && padding_algo &&
 406            !strcmp(padding_algo->name, "pss")) {
 407                if (EVP_PKEY_CTX_set_rsa_padding(ckey,
 408                                                 RSA_PKCS1_PSS_PADDING) <= 0) {
 409                        ret = rsa_err("Signer padding setup failed");
 410                        goto err_sign;
 411                }
 412        }
 413
 414        for (i = 0; i < region_count; i++) {
 415                if (!EVP_DigestSignUpdate(context, region[i].data,
 416                                          region[i].size)) {
 417                        ret = rsa_err("Signing data failed");
 418                        goto err_sign;
 419                }
 420        }
 421
 422        if (!EVP_DigestSignFinal(context, sig, &size)) {
 423                ret = rsa_err("Could not obtain signature");
 424                goto err_sign;
 425        }
 426
 427        EVP_MD_CTX_free(context);
 428
 429        debug("Got signature: %zu bytes, expected %d\n", size, EVP_PKEY_size(pkey));
 430        *sigp = sig;
 431        *sig_size = size;
 432
 433        return 0;
 434
 435err_sign:
 436        EVP_MD_CTX_free(context);
 437err_create:
 438        free(sig);
 439err_alloc:
 440        return ret;
 441}
 442
 443int rsa_sign(struct image_sign_info *info,
 444             const struct image_region region[], int region_count,
 445             uint8_t **sigp, uint *sig_len)
 446{
 447        EVP_PKEY *pkey = NULL;
 448        ENGINE *e = NULL;
 449        int ret;
 450
 451        ret = rsa_init();
 452        if (ret)
 453                return ret;
 454
 455        if (info->engine_id) {
 456                ret = rsa_engine_init(info->engine_id, &e);
 457                if (ret)
 458                        return ret;
 459        }
 460
 461        ret = rsa_get_priv_key(info->keydir, info->keyname, info->keyfile,
 462                               e, &pkey);
 463        if (ret)
 464                goto err_priv;
 465        ret = rsa_sign_with_key(pkey, info->padding, info->checksum, region,
 466                                region_count, sigp, sig_len);
 467        if (ret)
 468                goto err_sign;
 469
 470        EVP_PKEY_free(pkey);
 471        if (info->engine_id)
 472                rsa_engine_remove(e);
 473
 474        return ret;
 475
 476err_sign:
 477        EVP_PKEY_free(pkey);
 478err_priv:
 479        if (info->engine_id)
 480                rsa_engine_remove(e);
 481        return ret;
 482}
 483
 484/*
 485 * rsa_get_exponent(): - Get the public exponent from an RSA key
 486 */
 487static int rsa_get_exponent(RSA *key, uint64_t *e)
 488{
 489        int ret;
 490        BIGNUM *bn_te;
 491        const BIGNUM *key_e;
 492        uint64_t te;
 493
 494        ret = -EINVAL;
 495        bn_te = NULL;
 496
 497        if (!e)
 498                goto cleanup;
 499
 500        RSA_get0_key(key, NULL, &key_e, NULL);
 501        if (BN_num_bits(key_e) > 64)
 502                goto cleanup;
 503
 504        *e = BN_get_word(key_e);
 505
 506        if (BN_num_bits(key_e) < 33) {
 507                ret = 0;
 508                goto cleanup;
 509        }
 510
 511        bn_te = BN_dup(key_e);
 512        if (!bn_te)
 513                goto cleanup;
 514
 515        if (!BN_rshift(bn_te, bn_te, 32))
 516                goto cleanup;
 517
 518        if (!BN_mask_bits(bn_te, 32))
 519                goto cleanup;
 520
 521        te = BN_get_word(bn_te);
 522        te <<= 32;
 523        *e |= te;
 524        ret = 0;
 525
 526cleanup:
 527        if (bn_te)
 528                BN_free(bn_te);
 529
 530        return ret;
 531}
 532
 533/*
 534 * rsa_get_params(): - Get the important parameters of an RSA public key
 535 */
 536int rsa_get_params(RSA *key, uint64_t *exponent, uint32_t *n0_invp,
 537                   BIGNUM **modulusp, BIGNUM **r_squaredp)
 538{
 539        BIGNUM *big1, *big2, *big32, *big2_32;
 540        BIGNUM *n, *r, *r_squared, *tmp;
 541        const BIGNUM *key_n;
 542        BN_CTX *bn_ctx = BN_CTX_new();
 543        int ret = 0;
 544
 545        /* Initialize BIGNUMs */
 546        big1 = BN_new();
 547        big2 = BN_new();
 548        big32 = BN_new();
 549        r = BN_new();
 550        r_squared = BN_new();
 551        tmp = BN_new();
 552        big2_32 = BN_new();
 553        n = BN_new();
 554        if (!big1 || !big2 || !big32 || !r || !r_squared || !tmp || !big2_32 ||
 555            !n) {
 556                fprintf(stderr, "Out of memory (bignum)\n");
 557                return -ENOMEM;
 558        }
 559
 560        if (0 != rsa_get_exponent(key, exponent))
 561                ret = -1;
 562
 563        RSA_get0_key(key, &key_n, NULL, NULL);
 564        if (!BN_copy(n, key_n) || !BN_set_word(big1, 1L) ||
 565            !BN_set_word(big2, 2L) || !BN_set_word(big32, 32L))
 566                ret = -1;
 567
 568        /* big2_32 = 2^32 */
 569        if (!BN_exp(big2_32, big2, big32, bn_ctx))
 570                ret = -1;
 571
 572        /* Calculate n0_inv = -1 / n[0] mod 2^32 */
 573        if (!BN_mod_inverse(tmp, n, big2_32, bn_ctx) ||
 574            !BN_sub(tmp, big2_32, tmp))
 575                ret = -1;
 576        *n0_invp = BN_get_word(tmp);
 577
 578        /* Calculate R = 2^(# of key bits) */
 579        if (!BN_set_word(tmp, BN_num_bits(n)) ||
 580            !BN_exp(r, big2, tmp, bn_ctx))
 581                ret = -1;
 582
 583        /* Calculate r_squared = R^2 mod n */
 584        if (!BN_copy(r_squared, r) ||
 585            !BN_mul(tmp, r_squared, r, bn_ctx) ||
 586            !BN_mod(r_squared, tmp, n, bn_ctx))
 587                ret = -1;
 588
 589        *modulusp = n;
 590        *r_squaredp = r_squared;
 591
 592        BN_free(big1);
 593        BN_free(big2);
 594        BN_free(big32);
 595        BN_free(r);
 596        BN_free(tmp);
 597        BN_free(big2_32);
 598        if (ret) {
 599                fprintf(stderr, "Bignum operations failed\n");
 600                return -ENOMEM;
 601        }
 602
 603        return ret;
 604}
 605
 606int rsa_add_verify_data(struct image_sign_info *info, void *keydest)
 607{
 608        BIGNUM *modulus, *r_squared;
 609        uint64_t exponent;
 610        uint32_t n0_inv;
 611        int parent, node;
 612        char name[100];
 613        int ret;
 614        int bits;
 615        RSA *rsa;
 616        EVP_PKEY *pkey = NULL;
 617        ENGINE *e = NULL;
 618
 619        debug("%s: Getting verification data\n", __func__);
 620        if (info->engine_id) {
 621                ret = rsa_engine_init(info->engine_id, &e);
 622                if (ret)
 623                        return ret;
 624        }
 625        ret = rsa_get_pub_key(info->keydir, info->keyname, e, &pkey);
 626        if (ret)
 627                goto err_get_pub_key;
 628
 629        rsa = (RSA *)EVP_PKEY_get0_RSA(pkey);
 630        ret = rsa_get_params(rsa, &exponent, &n0_inv, &modulus, &r_squared);
 631        if (ret)
 632                goto err_get_params;
 633        bits = BN_num_bits(modulus);
 634        parent = fdt_subnode_offset(keydest, 0, FIT_SIG_NODENAME);
 635        if (parent == -FDT_ERR_NOTFOUND) {
 636                parent = fdt_add_subnode(keydest, 0, FIT_SIG_NODENAME);
 637                if (parent < 0) {
 638                        ret = parent;
 639                        if (ret != -FDT_ERR_NOSPACE) {
 640                                fprintf(stderr, "Couldn't create signature node: %s\n",
 641                                        fdt_strerror(parent));
 642                        }
 643                }
 644        }
 645        if (ret)
 646                goto done;
 647
 648        /* Either create or overwrite the named key node */
 649        snprintf(name, sizeof(name), "key-%s", info->keyname);
 650        node = fdt_subnode_offset(keydest, parent, name);
 651        if (node == -FDT_ERR_NOTFOUND) {
 652                node = fdt_add_subnode(keydest, parent, name);
 653                if (node < 0) {
 654                        ret = node;
 655                        if (ret != -FDT_ERR_NOSPACE) {
 656                                fprintf(stderr, "Could not create key subnode: %s\n",
 657                                        fdt_strerror(node));
 658                        }
 659                }
 660        } else if (node < 0) {
 661                fprintf(stderr, "Cannot select keys parent: %s\n",
 662                        fdt_strerror(node));
 663                ret = node;
 664        }
 665
 666        if (!ret) {
 667                ret = fdt_setprop_string(keydest, node, FIT_KEY_HINT,
 668                                         info->keyname);
 669        }
 670        if (!ret)
 671                ret = fdt_setprop_u32(keydest, node, "rsa,num-bits", bits);
 672        if (!ret)
 673                ret = fdt_setprop_u32(keydest, node, "rsa,n0-inverse", n0_inv);
 674        if (!ret) {
 675                ret = fdt_setprop_u64(keydest, node, "rsa,exponent", exponent);
 676        }
 677        if (!ret) {
 678                ret = fdt_add_bignum(keydest, node, "rsa,modulus", modulus,
 679                                     bits);
 680        }
 681        if (!ret) {
 682                ret = fdt_add_bignum(keydest, node, "rsa,r-squared", r_squared,
 683                                     bits);
 684        }
 685        if (!ret) {
 686                ret = fdt_setprop_string(keydest, node, FIT_ALGO_PROP,
 687                                         info->name);
 688        }
 689        if (!ret && info->require_keys) {
 690                ret = fdt_setprop_string(keydest, node, FIT_KEY_REQUIRED,
 691                                         info->require_keys);
 692        }
 693done:
 694        BN_free(modulus);
 695        BN_free(r_squared);
 696        if (ret)
 697                ret = ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
 698err_get_params:
 699        EVP_PKEY_free(pkey);
 700err_get_pub_key:
 701        if (info->engine_id)
 702                rsa_engine_remove(e);
 703
 704        if (ret)
 705                return ret;
 706
 707        return node;
 708}
 709