blob: b0493f9fbbda575c926c24ddb66d4ba1d49f5086 [file] [log] [blame]
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cryptohome/tpm1_static_utils.h"
#include <memory>
#include <base/logging.h>
#include <base/memory/free_deleter.h>
#include <base/strings/stringprintf.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <trousers/trousers.h>
#include "cryptohome/cryptolib.h"
using brillo::Blob;
using ScopedByteArray = std::unique_ptr<BYTE, base::FreeDeleter>;
namespace cryptohome {
std::string FormatTrousersErrorCode(TSS_RESULT result) {
return base::StringPrintf("TPM error 0x%x (%s)", result,
crypto::ScopedRSA ParseRsaFromTpmPubkeyBlob(const Blob& pubkey) {
// Parse the serialized TPM_PUBKEY.
UINT64 offset = 0;
BYTE* buffer = const_cast<BYTE*>(;
TPM_PUBKEY parsed;
TSS_RESULT tss_result = Trspi_UnloadBlob_PUBKEY(&offset, buffer, &parsed);
if (TPM_ERROR(tss_result)) {
LOG(ERROR) << "Failed to parse TPM_PUBKEY: "
<< FormatTrousersErrorCode(tss_result);
return nullptr;
ScopedByteArray scoped_key(parsed.pubKey.key);
ScopedByteArray scoped_parms(parsed.algorithmParms.parms);
crypto::ScopedRSA rsa(RSA_new());
if (!rsa) {
LOG(ERROR) << "Failed to create RSA object";
return nullptr;
// Get the public exponent.
if (!parms->exponentSize) {
rsa->e = BN_new();
if (!rsa->e) {
LOG(ERROR) << "Failed to create BN exponent";
return nullptr;
BN_set_word(rsa->e, kWellKnownExponent);
} else {
rsa->e = BN_bin2bn(parms->exponent, parms->exponentSize, nullptr);
if (!rsa->e) {
LOG(ERROR) << "Failed to load BN exponent from TPM_PUBKEY";
return nullptr;
// Get the modulus.
rsa->n = BN_bin2bn(parsed.pubKey.key, parsed.pubKey.keyLength, nullptr);
if (!rsa->n) {
LOG(ERROR) << "Failed to load BN modulus from TPM_PUBKEY";
return nullptr;
return rsa;
} // namespace cryptohome