summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Willden <swillden@google.com>2016-05-03 15:37:04 -0600
committerShawn Willden <swillden@google.com>2016-05-03 18:21:32 -0600
commitc8905b663d57b82afc8fadd72db85eb54c098637 (patch)
tree155e32a54fa48991f3ba8ae5b7313db476b1a1af
parentd487dc9e95162f249048bd31d4191a0d50b77496 (diff)
downloadandroid_system_keymaster-c8905b663d57b82afc8fadd72db85eb54c098637.tar.gz
android_system_keymaster-c8905b663d57b82afc8fadd72db85eb54c098637.tar.bz2
android_system_keymaster-c8905b663d57b82afc8fadd72db85eb54c098637.zip
Handle 64-bit attestation values on 32-bit platforms.
The BN_set_word OpenSSL function takes an unsigned long, which on 32-bit platforms (like fugu) is 32 bits, causing 64-bit values to be truncated. This CL adds a function that handles the conversion correctly on 32-bit platforms, and fails hard on platforms whose unsigned long is neither 64 nor 32 bits. Bug: 28558974 Change-Id: Iac2b23cf2cac3c035b3636ddd135666aaf15b40d
-rw-r--r--attestation_record.cpp34
-rw-r--r--include/keymaster/android_keymaster_utils.h2
2 files changed, 30 insertions, 6 deletions
diff --git a/attestation_record.cpp b/attestation_record.cpp
index befb8e2..8aed9ad 100644
--- a/attestation_record.cpp
+++ b/attestation_record.cpp
@@ -28,6 +28,28 @@
namespace keymaster {
+namespace {
+
+bool Uint64ToBignum(uint64_t value, BIGNUM* bn) {
+ static_assert(sizeof(unsigned long) == sizeof(uint64_t) ||
+ sizeof(unsigned long) == sizeof(uint32_t),
+ "Only 32 and 64-bit platforms supported");
+
+ if (sizeof(unsigned long) == sizeof(uint64_t)) {
+ return BN_set_word(bn, value);
+ } else if (sizeof(unsigned long) == sizeof(uint32_t)) {
+ uint32_t low_order = value & 0xFFFFFFFF;
+ uint32_t high_order = value >> 32;
+ return BN_set_word(bn, high_order) && //
+ BN_lshift(bn, bn, 32) && //
+ BN_add_word(bn, low_order);
+ } else {
+ return false;
+ }
+}
+
+} // anonymous namespace
+
struct stack_st_ASN1_TYPE_Delete {
void operator()(stack_st_ASN1_TYPE* p) { sk_ASN1_TYPE_free(p); }
};
@@ -333,20 +355,22 @@ static keymaster_error_t build_auth_list(const AuthorizationSet& auth_list, KM_A
assert((keymaster_tag_repeatable(entry.tag) && integer_set) ||
(!keymaster_tag_repeatable(entry.tag) && integer_ptr));
- UniquePtr<BIGNUM, BIGNUM_Delete> exponent(BN_new());
- if (!exponent.get())
+ UniquePtr<BIGNUM, BIGNUM_Delete> bn_value(BN_new());
+ if (!bn_value.get())
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
if (type == KM_DATE) {
- if (!BN_set_word(exponent.get(), entry.date_time))
+ if (!Uint64ToBignum(entry.date_time, bn_value.get())) {
return TranslateLastOpenSslError();
+ }
} else {
- if (!BN_set_word(exponent.get(), entry.long_integer))
+ if (!Uint64ToBignum(entry.long_integer, bn_value.get())) {
return TranslateLastOpenSslError();
+ }
}
UniquePtr<ASN1_INTEGER, ASN1_INTEGER_Delete> value(
- BN_to_ASN1_INTEGER(exponent.get(), nullptr));
+ BN_to_ASN1_INTEGER(bn_value.get(), nullptr));
if (!value.get())
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
diff --git a/include/keymaster/android_keymaster_utils.h b/include/keymaster/android_keymaster_utils.h
index 17688a6..a1cbf51 100644
--- a/include/keymaster/android_keymaster_utils.h
+++ b/include/keymaster/android_keymaster_utils.h
@@ -36,7 +36,7 @@ inline int64_t java_time(time_t time) {
// The exact meaning of a time_t value is implementation-dependent. If this code is ported to a
// platform that doesn't define it as "seconds since Jan 1, 1970 UTC", this function will have
// to be revised.
- return time * 1000;
+ return static_cast<int64_t>(time) * 1000;
}
/*