Home | History | Annotate | Download | only in lib
      1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
      2  * Use of this source code is governed by a BSD-style license that can be
      3  * found in the LICENSE file.
      4  *
      5  * Miscellaneous functions for userspace vboot utilities.
      6  */
      7 
      8 #include <openssl/bn.h>
      9 #include <openssl/rsa.h>
     10 
     11 #include <stdio.h>
     12 #include <stdlib.h>
     13 #include <string.h>
     14 #include <unistd.h>
     15 
     16 #include "cryptolib.h"
     17 #include "host_common.h"
     18 #include "util_misc.h"
     19 #include "vboot_common.h"
     20 
     21 void PrintPubKeySha1Sum(VbPublicKey *key)
     22 {
     23 	uint8_t *buf = ((uint8_t *)key) + key->key_offset;
     24 	uint64_t buflen = key->key_size;
     25 	uint8_t *digest = DigestBuf(buf, buflen, SHA1_DIGEST_ALGORITHM);
     26 	int i;
     27 	for (i = 0; i < SHA1_DIGEST_SIZE; i++)
     28 		printf("%02x", digest[i]);
     29 	free(digest);
     30 }
     31 
     32 int vb_keyb_from_rsa(struct rsa_st *rsa_private_key,
     33 		     uint8_t **keyb_data, uint32_t *keyb_size)
     34 {
     35 	uint32_t i, nwords;
     36 	BIGNUM *N = NULL;
     37 	BIGNUM *Big1 = NULL, *Big2 = NULL, *Big32 = NULL, *BigMinus1 = NULL;
     38 	BIGNUM *B = NULL;
     39 	BIGNUM *N0inv = NULL, *R = NULL, *RR = NULL;
     40 	BIGNUM *RRTemp = NULL, *NnumBits = NULL;
     41 	BIGNUM *n = NULL, *rr = NULL;
     42 	BN_CTX *bn_ctx = BN_CTX_new();
     43 	uint32_t n0invout;
     44 	uint32_t bufsize;
     45 	uint32_t *outbuf;
     46 	int retval = 1;
     47 
     48 	/* Size of RSA key in 32-bit words */
     49 	nwords = BN_num_bits(rsa_private_key->n) / 32;
     50 
     51 	bufsize = (2 + nwords + nwords) * sizeof(uint32_t);
     52 	outbuf = malloc(bufsize);
     53 	if (!outbuf)
     54 		goto done;
     55 
     56 	*keyb_data = (uint8_t *)outbuf;
     57 	*keyb_size = bufsize;
     58 
     59 	*outbuf++ = nwords;
     60 
     61 	/* Initialize BIGNUMs */
     62 #define NEW_BIGNUM(x) do { x = BN_new(); if (!x) goto done; } while (0)
     63 	NEW_BIGNUM(N);
     64 	NEW_BIGNUM(Big1);
     65 	NEW_BIGNUM(Big2);
     66 	NEW_BIGNUM(Big32);
     67 	NEW_BIGNUM(BigMinus1);
     68 	NEW_BIGNUM(N0inv);
     69 	NEW_BIGNUM(R);
     70 	NEW_BIGNUM(RR);
     71 	NEW_BIGNUM(RRTemp);
     72 	NEW_BIGNUM(NnumBits);
     73 	NEW_BIGNUM(n);
     74 	NEW_BIGNUM(rr);
     75 	NEW_BIGNUM(B);
     76 #undef NEW_BIGNUM
     77 
     78 	BN_copy(N, rsa_private_key->n);
     79 	BN_set_word(Big1, 1L);
     80 	BN_set_word(Big2, 2L);
     81 	BN_set_word(Big32, 32L);
     82 	BN_sub(BigMinus1, Big1, Big2);
     83 
     84 	BN_exp(B, Big2, Big32, bn_ctx); /* B = 2^32 */
     85 
     86 	/* Calculate and output N0inv = -1 / N[0] mod 2^32 */
     87 	BN_mod_inverse(N0inv, N, B, bn_ctx);
     88 	BN_sub(N0inv, B, N0inv);
     89 	n0invout = BN_get_word(N0inv);
     90 
     91 	*outbuf++ = n0invout;
     92 
     93 	/* Calculate R = 2^(# of key bits) */
     94 	BN_set_word(NnumBits, BN_num_bits(N));
     95 	BN_exp(R, Big2, NnumBits, bn_ctx);
     96 
     97 	/* Calculate RR = R^2 mod N */
     98 	BN_copy(RR, R);
     99 	BN_mul(RRTemp, RR, R, bn_ctx);
    100 	BN_mod(RR, RRTemp, N, bn_ctx);
    101 
    102 
    103 	/* Write out modulus as little endian array of integers. */
    104 	for (i = 0; i < nwords; ++i) {
    105 		uint32_t nout;
    106 
    107 		BN_mod(n, N, B, bn_ctx); /* n = N mod B */
    108 		nout = BN_get_word(n);
    109 		*outbuf++ = nout;
    110 
    111 		BN_rshift(N, N, 32); /*  N = N/B */
    112 	}
    113 
    114 	/* Write R^2 as little endian array of integers. */
    115 	for (i = 0; i < nwords; ++i) {
    116 		uint32_t rrout;
    117 
    118 		BN_mod(rr, RR, B, bn_ctx); /* rr = RR mod B */
    119 		rrout = BN_get_word(rr);
    120 		*outbuf++ = rrout;
    121 
    122 		BN_rshift(RR, RR, 32); /* RR = RR/B */
    123 	}
    124 
    125 	outbuf = NULL;
    126 	retval = 0;
    127 
    128 done:
    129 	free(outbuf);
    130 	/* Free BIGNUMs. */
    131 	BN_free(Big1);
    132 	BN_free(Big2);
    133 	BN_free(Big32);
    134 	BN_free(BigMinus1);
    135 	BN_free(N0inv);
    136 	BN_free(R);
    137 	BN_free(RRTemp);
    138 	BN_free(NnumBits);
    139 	BN_free(n);
    140 	BN_free(rr);
    141 
    142 	return retval;
    143 }
    144