const char *private_key_sha1_string(const struct vb2_private_key *key) { uint8_t *buf; uint32_t buflen; uint8_t digest[VB2_SHA1_DIGEST_SIZE]; static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1]; if (!key->rsa_private_key || vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen)) { return "<error>"; } vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, sizeof(digest)); char *dnext = dest; int i; for (i = 0; i < sizeof(digest); i++) dnext += sprintf(dnext, "%02x", digest[i]); free(buf); return dest; }
static int vb1_make_keypair() { VbPrivateKey *privkey = 0; VbPublicKey *pubkey = 0; RSA *rsa_key = 0; uint8_t *keyb_data = 0; uint32_t keyb_size; enum vb2_signature_algorithm sig_alg; uint64_t vb1_algorithm; FILE *fp; int ret = 1; fp = fopen(infile, "rb"); if (!fp) { fprintf(stderr, "Unable to open %s\n", infile); goto done; } rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); fclose(fp); if (!rsa_key) { fprintf(stderr, "Unable to read RSA key from %s\n", infile); goto done; } sig_alg = vb2_rsa_sig_alg(rsa_key); if (sig_alg == VB2_SIG_INVALID) { fprintf(stderr, "Unsupported sig algorithm in RSA key\n"); goto done; } /* combine the sig_alg with the hash_alg to get the vb1 algorithm */ vb1_algorithm = (sig_alg - VB2_SIG_RSA1024) * 3 + opt_hash_alg - VB2_HASH_SHA1; /* Create the private key */ privkey = (VbPrivateKey *)malloc(sizeof(VbPrivateKey)); if (!privkey) goto done; privkey->rsa_private_key = rsa_key; privkey->algorithm = vb1_algorithm; /* Write it out */ strcpy(outext, ".vbprivk"); if (0 != PrivateKeyWrite(outfile, privkey)) { fprintf(stderr, "unable to write private key\n"); goto done; } fprintf(stderr, "wrote %s\n", outfile); /* Create the public key */ ret = vb_keyb_from_rsa(rsa_key, &keyb_data, &keyb_size); if (ret) { fprintf(stderr, "couldn't extract the public key\n"); goto done; } pubkey = PublicKeyAlloc(keyb_size, vb1_algorithm, opt_version); if (!pubkey) goto done; memcpy(GetPublicKeyData(pubkey), keyb_data, keyb_size); /* Write it out */ strcpy(outext, ".vbpubk"); if (0 != PublicKeyWrite(outfile, pubkey)) { fprintf(stderr, "unable to write public key\n"); goto done; } fprintf(stderr, "wrote %s\n", outfile); ret = 0; done: free(privkey); free(pubkey); free(keyb_data); RSA_free(rsa_key); return ret; }
static int vb2_make_keypair() { struct vb2_private_key *privkey = 0; struct vb2_public_key *pubkey = 0; RSA *rsa_key = 0; uint8_t *keyb_data = 0; uint32_t keyb_size; enum vb2_signature_algorithm sig_alg; uint8_t *pubkey_buf = 0; int has_priv = 0; FILE *fp; int ret = 1; fp = fopen(infile, "rb"); if (!fp) { fprintf(stderr, "Unable to open %s\n", infile); goto done; } rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); if (!rsa_key) { /* Check if the PEM contains only a public key */ fseek(fp, 0, SEEK_SET); rsa_key = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL); } fclose(fp); if (!rsa_key) { fprintf(stderr, "Unable to read RSA key from %s\n", infile); goto done; } /* Public keys doesn't have the private exponent */ has_priv = !!rsa_key->d; if (!has_priv) fprintf(stderr, "%s has a public key only.\n", infile); sig_alg = vb2_rsa_sig_alg(rsa_key); if (sig_alg == VB2_SIG_INVALID) { fprintf(stderr, "Unsupported sig algorithm in RSA key\n"); goto done; } if (has_priv) { /* Create the private key */ privkey = calloc(1, sizeof(*privkey)); if (!privkey) { fprintf(stderr, "Unable to allocate the private key\n"); goto done; } privkey->rsa_private_key = rsa_key; privkey->sig_alg = sig_alg; privkey->hash_alg = opt_hash_alg; if (opt_desc && vb2_private_key_set_desc(privkey, opt_desc)) { fprintf(stderr, "Unable to set the private key description\n"); goto done; } } /* Create the public key */ if (vb2_public_key_alloc(&pubkey, sig_alg)) { fprintf(stderr, "Unable to allocate the public key\n"); goto done; } /* Extract the keyb blob */ if (vb_keyb_from_rsa(rsa_key, &keyb_data, &keyb_size)) { fprintf(stderr, "Couldn't extract the public key\n"); goto done; } /* * Copy the keyb blob to the public key's buffer, because that's where * vb2_unpack_key_data() and vb2_public_key_pack() expect to find it. */ pubkey_buf = vb2_public_key_packed_data(pubkey); memcpy(pubkey_buf, keyb_data, keyb_size); /* Fill in the internal struct pointers */ if (vb2_unpack_key_data(pubkey, pubkey_buf, keyb_size)) { fprintf(stderr, "Unable to unpack the public key blob\n"); goto done; } pubkey->hash_alg = opt_hash_alg; pubkey->version = opt_version; if (opt_desc && vb2_public_key_set_desc(pubkey, opt_desc)) { fprintf(stderr, "Unable to set pubkey description\n"); goto done; } /* Update the IDs */ if (!force_id) { uint8_t *digest = DigestBuf(keyb_data, keyb_size, SHA1_DIGEST_ALGORITHM); memcpy(&opt_id, digest, sizeof(opt_id)); free(digest); } memcpy((struct vb2_id *)pubkey->id, &opt_id, sizeof(opt_id)); /* Write them out */ if (has_priv) { privkey->id = opt_id; strcpy(outext, ".vbprik2"); if (vb2_private_key_write(privkey, outfile)) { fprintf(stderr, "unable to write private key\n"); goto done; } fprintf(stderr, "wrote %s\n", outfile); } strcpy(outext, ".vbpubk2"); if (vb2_public_key_write(pubkey, outfile)) { fprintf(stderr, "unable to write public key\n"); goto done; } fprintf(stderr, "wrote %s\n", outfile); ret = 0; done: RSA_free(rsa_key); if (privkey) /* prevent double-free */ privkey->rsa_private_key = 0; vb2_private_key_free(privkey); vb2_public_key_free(pubkey); free(keyb_data); return ret; }
static int vb2_make_keypair() { struct vb2_private_key *privkey = 0; struct vb2_public_key *pubkey = 0; RSA *rsa_key = 0; uint8_t *keyb_data = 0; uint32_t keyb_size; enum vb2_signature_algorithm sig_alg; uint8_t *pubkey_buf = 0; FILE *fp; int ret = 1; fp = fopen(infile, "rb"); if (!fp) { fprintf(stderr, "Unable to open %s\n", infile); goto done; } rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); fclose(fp); if (!rsa_key) { fprintf(stderr, "Unable to read RSA key from %s\n", infile); goto done; } sig_alg = vb2_rsa_sig_alg(rsa_key); if (sig_alg == VB2_SIG_INVALID) { fprintf(stderr, "Unsupported sig algorithm in RSA key\n"); goto done; } /* Create the private key */ privkey = calloc(1, sizeof(*privkey)); if (!privkey) { fprintf(stderr, "Unable to allocate the private key\n"); goto done; } privkey->rsa_private_key = rsa_key; privkey->sig_alg = sig_alg; privkey->hash_alg = opt_hash_alg; privkey->guid = opt_guid; if (opt_desc && vb2_private_key_set_desc(privkey, opt_desc)) { fprintf(stderr, "Unable to set the private key description\n"); goto done; } /* Write it out */ strcpy(outext, ".vbprik2"); if (vb2_private_key_write(privkey, outfile)) { fprintf(stderr, "unable to write private key\n"); goto done; } fprintf(stderr, "wrote %s\n", outfile); /* Create the public key */ if (vb2_public_key_alloc(&pubkey, sig_alg)) { fprintf(stderr, "Unable to allocate the public key\n"); goto done; } /* Extract the keyb blob */ if (vb_keyb_from_rsa(rsa_key, &keyb_data, &keyb_size)) { fprintf(stderr, "Couldn't extract the public key\n"); goto done; } /* * Copy the keyb blob to the public key's buffer, because that's where * vb2_unpack_key_data() and vb2_public_key_pack() expect to find it. */ pubkey_buf = vb2_public_key_packed_data(pubkey); memcpy(pubkey_buf, keyb_data, keyb_size); /* Fill in the internal struct pointers */ if (vb2_unpack_key_data(pubkey, pubkey_buf, keyb_size)) { fprintf(stderr, "Unable to unpack the public key blob\n"); goto done; } pubkey->hash_alg = opt_hash_alg; pubkey->version = opt_version; memcpy((struct vb2_guid *)pubkey->guid, &opt_guid, sizeof(opt_guid)); if (opt_desc && vb2_public_key_set_desc(pubkey, opt_desc)) { fprintf(stderr, "Unable to set pubkey description\n"); goto done; } /* Write it out */ strcpy(outext, ".vbpubk2"); if (vb2_public_key_write(pubkey, outfile)) { fprintf(stderr, "unable to write public key\n"); goto done; } fprintf(stderr, "wrote %s\n", outfile); ret = 0; done: RSA_free(rsa_key); if (privkey) /* prevent double-free */ privkey->rsa_private_key = 0; vb2_private_key_free(privkey); vb2_public_key_free(pubkey); free(keyb_data); return ret; }
int ft_sign_usbpd1(const char *name, uint8_t *buf, uint32_t len, void *data) { struct vb2_private_key *key_ptr = 0; struct vb2_signature *sig_ptr = 0; uint8_t *keyb_data = 0; uint32_t keyb_size; int retval = 1; uint32_t sig_size; uint32_t sig_offset; uint32_t pub_size; uint32_t pub_offset; uint32_t ro_size; uint32_t rw_size; uint32_t ro_offset; uint32_t rw_offset; uint32_t r; Debug("%s(): name %s\n", __func__, name); Debug("%s(): len 0x%08x (%d)\n", __func__, len, len); /* Get image locations */ if (!parse_size_opts(len, &ro_size, &rw_size, &ro_offset, &rw_offset)) goto done; /* Read the signing keypair file */ if (vb2_private_key_read_pem(&key_ptr, sign_option.pem_signpriv)) { fprintf(stderr, "Unable to read keypair from %s\n", sign_option.pem_signpriv); goto done; } /* Set the algs */ key_ptr->hash_alg = sign_option.hash_alg; key_ptr->sig_alg = vb2_rsa_sig_alg(key_ptr->rsa_private_key); if (key_ptr->sig_alg == VB2_SIG_INVALID) { fprintf(stderr, "Unsupported sig algorithm in RSA key\n"); goto done; } /* Figure out what needs signing */ sig_size = vb2_rsa_sig_size(key_ptr->sig_alg); if (rw_size < sig_size) { fprintf(stderr, "The RW image is too small to hold the signature" " (0x%08x < %08x)\n", rw_size, sig_size); goto done; } rw_size -= sig_size; sig_offset = rw_offset + rw_size; Debug("rw_size => 0x%08x\n", rw_size); Debug("rw_offset => 0x%08x\n", rw_offset); Debug("sig_size 0x%08x\n", sig_size); Debug("sig_offset 0x%08x\n", sig_offset); /* Sign the blob */ r = vb2_sign_data(&sig_ptr, buf + rw_offset, rw_size, key_ptr, "Bah"); if (r) { fprintf(stderr, "Unable to sign data (error 0x%08x, if that helps)\n", r); goto done; } /* Double-check the size */ if (sig_ptr->sig_size != sig_size) { fprintf(stderr, "ERROR: sig size is %d bytes, not %d as expected.\n", sig_ptr->sig_size, sig_size); goto done; } /* Okay, looking good. Update the signature. */ memcpy(buf + sig_offset, (uint8_t *)sig_ptr + sig_ptr->sig_offset, sig_ptr->sig_size); /* If there's no RO section, we're done. */ if (!ro_size) { retval = 0; goto done; } /* Otherwise, now update the public key */ if (vb_keyb_from_rsa(key_ptr->rsa_private_key, &keyb_data, &keyb_size)) { fprintf(stderr, "Couldn't extract the public key\n"); goto done; } Debug("keyb_size is 0x%x (%d):\n", keyb_size, keyb_size); /* * Of course the packed public key format is different. Why would you * think otherwise? Since the dawn of time, vboot has used this: * * uint32_t nwords size of RSA key in 32-bit words * uint32_t n0inv magic RSA n0inv * uint32_t n[nwords] magic RSA modulus little endian array * uint32_t rr[nwords] magic RSA R^2 little endian array * * But for no discernable reason, the usbpd1 format uses this: * * uint32_t n[nwords] magic RSA modulus little endian array * uint32_t rr[nwords] magic RSA R^2 little endian array * uint32_t n0inv magic RSA n0inv * * There's no nwords field, and n0inv is last insted of first. Sigh. */ pub_size = keyb_size - 4; /* align pubkey size to 16-byte boundary */ uint32_t pub_pad = pub_size; pub_size = (pub_size + 16) / 16 * 16; pub_pad = pub_size - pub_pad; pub_offset = ro_offset + ro_size - pub_size; if (ro_size < pub_size) { fprintf(stderr, "The RO image is too small to hold the public key" " (0x%08x < %08x)\n", ro_size, pub_size); goto done; } /* How many bytes in the arrays? */ uint32_t nbytes = 4 * (*(uint32_t *)keyb_data); /* Source offsets from keyb_data */ uint32_t src_ofs_n0inv = 4; uint32_t src_ofs_n = src_ofs_n0inv + 4; uint32_t src_ofs_rr = src_ofs_n + nbytes; /* Dest offsets from buf */ uint32_t dst_ofs_n = pub_offset + 0; uint32_t dst_ofs_rr = dst_ofs_n + nbytes; uint32_t dst_ofs_n0inv = dst_ofs_rr + nbytes; Debug("len 0x%08x ro_size 0x%08x ro_offset 0x%08x\n", len, ro_size, ro_offset); Debug("pub_size 0x%08x pub_offset 0x%08x nbytes 0x%08x\n", pub_size, pub_offset, nbytes); Debug("pub_pad 0x%08x\n", pub_pad); /* Copy n[nwords] */ memcpy(buf + dst_ofs_n, keyb_data + src_ofs_n, nbytes); /* Copy rr[nwords] */ memcpy(buf + dst_ofs_rr, keyb_data + src_ofs_rr, nbytes); /* Copy n0inv */ memcpy(buf + dst_ofs_n0inv, keyb_data + src_ofs_n0inv, 4); /* Pad with 0xff */ memset(buf + dst_ofs_n0inv + 4, 0xff, pub_pad); /* Finally */ retval = 0; done: if (key_ptr) vb2_private_key_free(key_ptr); if (keyb_data) free(keyb_data); return retval; }