blob: 3abf3eb6ca66435a4ae73f0df4247bd353e84f8d [file] [log] [blame] [edit]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libhwsec/backend/tpm1/signing.h"
#include <brillo/secure_blob.h>
#include <libhwsec-foundation/crypto/sha.h>
#include <libhwsec-foundation/status/status_chain_macros.h>
#include "libhwsec/backend/digest_algorithms.h"
#include "libhwsec/error/tpm1_error.h"
#include "libhwsec/overalls/overalls.h"
#include "libhwsec/status.h"
#include "libhwsec/tss_utils/scoped_tss_type.h"
using brillo::BlobFromString;
using hwsec_foundation::Sha256;
using hwsec_foundation::status::MakeStatus;
namespace hwsec {
StatusOr<brillo::Blob> SigningTpm1::Sign(Key key,
const brillo::Blob& data,
const SigningOptions& options) {
ASSIGN_OR_RETURN(const brillo::Blob& hashed_data,
DigestData(options.digest_algorithm, data));
return RawSign(key, hashed_data, options);
}
StatusOr<brillo::Blob> SigningTpm1::RawSign(Key key,
const brillo::Blob& data,
const SigningOptions& options) {
if (options.rsa_padding_scheme.value_or(
SigningOptions::RsaPaddingScheme::kPkcs1v15) !=
SigningOptions::RsaPaddingScheme::kPkcs1v15) {
return MakeStatus<TPMError>("Unsupported mechanism for tpm1.2 key",
TPMRetryAction::kNoRetry);
}
ASSIGN_OR_RETURN(const KeyTpm1& key_data, key_management_.GetKeyData(key),
_.WithStatus<TPMError>("Failed to get the key data"));
ASSIGN_OR_RETURN(TSS_HCONTEXT context, tss_helper_.GetTssContext());
// Create a hash object to hold the input.
ScopedTssObject<TSS_HHASH> hash_handle(overalls_, context);
RETURN_IF_ERROR(
MakeStatus<TPM1Error>(overalls_.Ospi_Context_CreateObject(
context, TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, hash_handle.ptr())))
.WithStatus<TPMError>("Failed to create hash object");
// Create the DER encoded input.
ASSIGN_OR_RETURN(const brillo::Blob& der_header,
GetDigestAlgorithmEncoding(options.digest_algorithm));
brillo::Blob der_encoded_input = brillo::CombineBlobs({der_header, data});
RETURN_IF_ERROR(
MakeStatus<TPM1Error>(overalls_.Ospi_Hash_SetHashValue(
hash_handle, der_encoded_input.size(), der_encoded_input.data())))
.WithStatus<TPMError>("Failed to set hash data");
uint32_t length = 0;
ScopedTssMemory buffer(overalls_, context);
RETURN_IF_ERROR(MakeStatus<TPM1Error>(overalls_.Ospi_Hash_Sign(
hash_handle, key_data.key_handle, &length, buffer.ptr())))
.WithStatus<TPMError>("Failed to generate signature");
return brillo::Blob(buffer.value(), buffer.value() + length);
}
Status SigningTpm1::Verify(Key key, const brillo::Blob& signed_data) {
return MakeStatus<TPMError>("Unimplemented", TPMRetryAction::kNoRetry);
}
} // namespace hwsec