marlin/eas: Fixing foreground/schedtune.boost path.
am: 7ac34d0
* commit '7ac34d08efb3290bab77c6ed3bbbec067aeddf09':
marlin/eas: Fixing foreground/schedtune.boost path.
Change-Id: I0a549cb1fe0e5bd5ce89a7178d1468f808f175f7
diff --git a/adb/Android.mk b/adb/Android.mk
index f1d3bee..6693619 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -108,7 +108,7 @@
# Even though we're building a static library (and thus there's no link step for
# this to take effect), this adds the includes to our path.
-LOCAL_STATIC_LIBRARIES := libbase
+LOCAL_STATIC_LIBRARIES := libcrypto_utils_static libcrypto_static libbase
include $(BUILD_STATIC_LIBRARY)
@@ -131,7 +131,7 @@
# Even though we're building a static library (and thus there's no link step for
# this to take effect), this adds the includes to our path.
-LOCAL_STATIC_LIBRARIES := libcrypto_static libbase
+LOCAL_STATIC_LIBRARIES := libcrypto_utils_static libcrypto_static libbase
LOCAL_C_INCLUDES_windows := development/host/windows/usb/api/
LOCAL_MULTILIB := first
@@ -151,7 +151,7 @@
shell_service_test.cpp \
LOCAL_SANITIZE := $(adb_target_sanitize)
-LOCAL_STATIC_LIBRARIES := libadbd
+LOCAL_STATIC_LIBRARIES := libadbd libcrypto_utils_static libcrypto_static
LOCAL_SHARED_LIBRARIES := liblog libbase libcutils
include $(BUILD_NATIVE_TEST)
@@ -191,6 +191,7 @@
LOCAL_SHARED_LIBRARIES := libbase
LOCAL_STATIC_LIBRARIES := \
libadb \
+ libcrypto_utils_static \
libcrypto_static \
libcutils \
libdiagnose_usb \
@@ -219,7 +220,7 @@
LOCAL_SRC_FILES := test_track_devices.cpp
LOCAL_SANITIZE := $(adb_host_sanitize)
LOCAL_SHARED_LIBRARIES := libbase
-LOCAL_STATIC_LIBRARIES := libadb libcrypto_static libcutils
+LOCAL_STATIC_LIBRARIES := libadb libcrypto_utils_static libcrypto_static libcutils
LOCAL_LDLIBS += -lrt -ldl -lpthread
include $(BUILD_HOST_EXECUTABLE)
endif
@@ -271,6 +272,7 @@
LOCAL_STATIC_LIBRARIES := \
libadb \
libbase \
+ libcrypto_utils_static \
libcrypto_static \
libdiagnose_usb \
liblog \
@@ -342,11 +344,11 @@
libfec_rs \
libselinux \
liblog \
- libmincrypt \
libext4_utils_static \
libsquashfs_utils \
libcutils \
libbase \
+ libcrypto_utils_static \
libcrypto_static \
libminijail
diff --git a/adb/adb.cpp b/adb/adb.cpp
index e0c0503..49d2936 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -353,7 +353,8 @@
send_auth_publickey(t);
}
} else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
- if (adb_auth_verify(t->token, p->data, p->msg.data_length)) {
+ if (adb_auth_verify(t->token, sizeof(t->token),
+ p->data, p->msg.data_length)) {
adb_auth_verified(t);
t->failed_auth_attempts = 0;
} else {
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index a13604a..1ab5e1a 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -43,9 +43,15 @@
void *adb_auth_nextkey(void *current);
int adb_auth_get_userkey(unsigned char *data, size_t len);
-static inline int adb_auth_generate_token(void *token, size_t token_size) { return 0; }
-static inline int adb_auth_verify(void *token, void *sig, int siglen) { return 0; }
-static inline void adb_auth_confirm_key(unsigned char *data, size_t len, atransport *t) { }
+static inline int adb_auth_generate_token(void *token, size_t token_size) {
+ return 0;
+}
+static inline int adb_auth_verify(void *token, size_t token_size,
+ void *sig, int siglen) {
+ return 0;
+}
+static inline void adb_auth_confirm_key(unsigned char *data, size_t len,
+ atransport *t) {}
#else // !ADB_HOST
@@ -54,12 +60,15 @@
return 0;
}
static inline void *adb_auth_nextkey(void *current) { return NULL; }
-static inline int adb_auth_get_userkey(unsigned char *data, size_t len) { return 0; }
+static inline int adb_auth_get_userkey(unsigned char *data, size_t len) {
+ return 0;
+}
void adbd_auth_init(void);
void adbd_cloexec_auth_socket();
int adb_auth_generate_token(void *token, size_t token_size);
-int adb_auth_verify(uint8_t* token, uint8_t* sig, int siglen);
+int adb_auth_verify(uint8_t* token, size_t token_size,
+ uint8_t* sig, int siglen);
void adb_auth_confirm_key(unsigned char *data, size_t len, atransport *t);
#endif // ADB_HOST
diff --git a/adb/adb_auth_client.cpp b/adb/adb_auth_client.cpp
index 128c3df..415ab8e 100644
--- a/adb/adb_auth_client.cpp
+++ b/adb/adb_auth_client.cpp
@@ -23,10 +23,14 @@
#include <stdio.h>
#include <string.h>
+#include <openssl/obj_mac.h>
+#include <openssl/rsa.h>
+#include <openssl/sha.h>
+
+#include <crypto_utils/android_pubkey.h>
+
#include "cutils/list.h"
#include "cutils/sockets.h"
-#include "mincrypt/rsa.h"
-#include "mincrypt/sha.h"
#include "adb.h"
#include "fdevent.h"
@@ -34,7 +38,7 @@
struct adb_public_key {
struct listnode node;
- RSAPublicKey key;
+ RSA* key;
};
static const char *key_paths[] = {
@@ -66,9 +70,8 @@
}
while (fgets(buf, sizeof(buf), f)) {
- /* Allocate 4 extra bytes to decode the base64 data in-place */
auto key = reinterpret_cast<adb_public_key*>(
- calloc(1, sizeof(adb_public_key) + 4));
+ calloc(1, sizeof(adb_public_key)));
if (key == nullptr) {
D("Can't malloc key");
break;
@@ -78,15 +81,18 @@
if (sep)
*sep = '\0';
- ret = __b64_pton(buf, (u_char *)&key->key, sizeof(key->key) + 4);
- if (ret != sizeof(key->key)) {
+ // b64_pton requires one additional byte in the target buffer for
+ // decoding to succeed. See http://b/28035006 for details.
+ uint8_t keybuf[ANDROID_PUBKEY_ENCODED_SIZE + 1];
+ ret = __b64_pton(buf, keybuf, sizeof(keybuf));
+ if (ret != ANDROID_PUBKEY_ENCODED_SIZE) {
D("%s: Invalid base64 data ret=%d", file, ret);
free(key);
continue;
}
- if (key->key.len != RSANUMWORDS) {
- D("%s: Invalid key len %d", file, key->key.len);
+ if (!android_pubkey_decode(keybuf, ret, &key->key)) {
+ D("%s: Failed to parse key", file);
free(key);
continue;
}
@@ -104,7 +110,9 @@
while (!list_empty(list)) {
item = list_head(list);
list_remove(item);
- free(node_to_item(item, struct adb_public_key, node));
+ adb_public_key* key = node_to_item(item, struct adb_public_key, node);
+ RSA_free(key->key);
+ free(key);
}
}
@@ -139,20 +147,17 @@
return ret * token_size;
}
-int adb_auth_verify(uint8_t* token, uint8_t* sig, int siglen)
+int adb_auth_verify(uint8_t* token, size_t token_size, uint8_t* sig, int siglen)
{
struct listnode *item;
struct listnode key_list;
int ret = 0;
- if (siglen != RSANUMBYTES)
- return 0;
-
load_keys(&key_list);
list_for_each(item, &key_list) {
adb_public_key* key = node_to_item(item, struct adb_public_key, node);
- ret = RSA_verify(&key->key, sig, siglen, token, SHA_DIGEST_SIZE);
+ ret = RSA_verify(NID_sha1, token, token_size, sig, siglen, key->key);
if (ret)
break;
}
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index 8f154fd..ab641eb 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -37,14 +37,9 @@
#include "adb.h"
-/* HACK: we need the RSAPublicKey struct
- * but RSA_verify conflits with openssl */
-#define RSA_verify RSA_verify_mincrypt
-#include "mincrypt/rsa.h"
-#undef RSA_verify
-
#include <android-base/errors.h>
#include <android-base/strings.h>
+#include <crypto_utils/android_pubkey.h>
#include <cutils/list.h>
#include <openssl/evp.h>
@@ -68,54 +63,6 @@
static struct listnode key_list;
-/* Convert OpenSSL RSA private key to android pre-computed RSAPublicKey format */
-static int RSA_to_RSAPublicKey(RSA *rsa, RSAPublicKey *pkey)
-{
- int ret = 1;
- unsigned int i;
-
- BN_CTX* ctx = BN_CTX_new();
- BIGNUM* r32 = BN_new();
- BIGNUM* rr = BN_new();
- BIGNUM* r = BN_new();
- BIGNUM* rem = BN_new();
- BIGNUM* n = BN_new();
- BIGNUM* n0inv = BN_new();
-
- if (RSA_size(rsa) != RSANUMBYTES) {
- ret = 0;
- goto out;
- }
-
- BN_set_bit(r32, 32);
- BN_copy(n, rsa->n);
- BN_set_bit(r, RSANUMWORDS * 32);
- BN_mod_sqr(rr, r, n, ctx);
- BN_div(NULL, rem, n, r32, ctx);
- BN_mod_inverse(n0inv, rem, r32, ctx);
-
- pkey->len = RSANUMWORDS;
- pkey->n0inv = 0 - BN_get_word(n0inv);
- for (i = 0; i < RSANUMWORDS; i++) {
- BN_div(rr, rem, rr, r32, ctx);
- pkey->rr[i] = BN_get_word(rem);
- BN_div(n, rem, n, r32, ctx);
- pkey->n[i] = BN_get_word(rem);
- }
- pkey->exponent = BN_get_word(rsa->e);
-
-out:
- BN_free(n0inv);
- BN_free(n);
- BN_free(rem);
- BN_free(r);
- BN_free(rr);
- BN_free(r32);
- BN_CTX_free(ctx);
-
- return ret;
-}
-
static void get_user_info(char *buf, size_t len)
{
char hostname[1024], username[1024];
@@ -156,53 +103,55 @@
static int write_public_keyfile(RSA *private_key, const char *private_key_path)
{
- RSAPublicKey pkey;
+ uint8_t binary_key_data[ANDROID_PUBKEY_ENCODED_SIZE];
+ uint8_t* base64_key_data = nullptr;
+ size_t base64_key_length = 0;
FILE *outfile = NULL;
char path[PATH_MAX], info[MAX_PAYLOAD_V1];
- uint8_t* encoded = nullptr;
- size_t encoded_length;
int ret = 0;
- if (snprintf(path, sizeof(path), "%s.pub", private_key_path) >=
- (int)sizeof(path)) {
- D("Path too long while writing public key");
- return 0;
- }
-
- if (!RSA_to_RSAPublicKey(private_key, &pkey)) {
+ if (!android_pubkey_encode(private_key, binary_key_data,
+ sizeof(binary_key_data))) {
D("Failed to convert to publickey");
- return 0;
- }
-
- outfile = fopen(path, "w");
- if (!outfile) {
- D("Failed to open '%s'", path);
- return 0;
+ goto out;
}
D("Writing public key to '%s'", path);
#if defined(OPENSSL_IS_BORINGSSL)
- if (!EVP_EncodedLength(&encoded_length, sizeof(pkey))) {
+ if (!EVP_EncodedLength(&base64_key_length, sizeof(binary_key_data))) {
D("Public key too large to base64 encode");
goto out;
}
#else
/* While we switch from OpenSSL to BoringSSL we have to implement
* |EVP_EncodedLength| here. */
- encoded_length = 1 + ((sizeof(pkey) + 2) / 3 * 4);
+ base64_key_length = 1 + ((sizeof(binary_key_data) + 2) / 3 * 4);
#endif
- encoded = new uint8_t[encoded_length];
- if (encoded == nullptr) {
+ base64_key_data = new uint8_t[base64_key_length];
+ if (base64_key_data == nullptr) {
D("Allocation failure");
goto out;
}
- encoded_length = EVP_EncodeBlock(encoded, (uint8_t*) &pkey, sizeof(pkey));
+ base64_key_length = EVP_EncodeBlock(base64_key_data, binary_key_data,
+ sizeof(binary_key_data));
get_user_info(info, sizeof(info));
- if (fwrite(encoded, encoded_length, 1, outfile) != 1 ||
+ if (snprintf(path, sizeof(path), "%s.pub", private_key_path) >=
+ (int)sizeof(path)) {
+ D("Path too long while writing public key");
+ goto out;
+ }
+
+ outfile = fopen(path, "w");
+ if (!outfile) {
+ D("Failed to open '%s'", path);
+ goto out;
+ }
+
+ if (fwrite(base64_key_data, base64_key_length, 1, outfile) != 1 ||
fwrite(info, strlen(info), 1, outfile) != 1) {
D("Write error while writing public key");
goto out;
@@ -214,7 +163,7 @@
if (outfile != NULL) {
fclose(outfile);
}
- delete[] encoded;
+ delete[] base64_key_data;
return ret;
}
diff --git a/adb/adb_io_test.cpp b/adb/adb_io_test.cpp
index 21a82e8..611b239 100644
--- a/adb/adb_io_test.cpp
+++ b/adb/adb_io_test.cpp
@@ -37,7 +37,13 @@
// fds far from the range that open() returns. But all of that might defeat the
// purpose of the tests.
-TEST(io, ReadFdExactly_whole) {
+#if defined(_WIN32)
+#define POSIX_TEST(x,y) TEST(DISABLED_ ## x,y)
+#else
+#define POSIX_TEST TEST
+#endif
+
+POSIX_TEST(io, ReadFdExactly_whole) {
const char expected[] = "Foobar";
TemporaryFile tf;
ASSERT_NE(-1, tf.fd);
@@ -51,7 +57,7 @@
EXPECT_STREQ(expected, buf);
}
-TEST(io, ReadFdExactly_eof) {
+POSIX_TEST(io, ReadFdExactly_eof) {
const char expected[] = "Foobar";
TemporaryFile tf;
ASSERT_NE(-1, tf.fd);
@@ -65,7 +71,7 @@
EXPECT_EQ(0, errno) << strerror(errno);
}
-TEST(io, ReadFdExactly_partial) {
+POSIX_TEST(io, ReadFdExactly_partial) {
const char input[] = "Foobar";
TemporaryFile tf;
ASSERT_NE(-1, tf.fd);
@@ -82,7 +88,7 @@
EXPECT_STREQ(expected.c_str(), buf);
}
-TEST(io, WriteFdExactly_whole) {
+POSIX_TEST(io, WriteFdExactly_whole) {
const char expected[] = "Foobar";
TemporaryFile tf;
ASSERT_NE(-1, tf.fd);
@@ -97,7 +103,7 @@
EXPECT_STREQ(expected, s.c_str());
}
-TEST(io, WriteFdExactly_partial) {
+POSIX_TEST(io, WriteFdExactly_partial) {
const char buf[] = "Foobar";
TemporaryFile tf;
ASSERT_NE(-1, tf.fd);
@@ -114,7 +120,7 @@
EXPECT_EQ(expected, s);
}
-TEST(io, WriteFdExactly_ENOSPC) {
+POSIX_TEST(io, WriteFdExactly_ENOSPC) {
int fd = open("/dev/full", O_WRONLY);
ASSERT_NE(-1, fd);
@@ -123,7 +129,7 @@
ASSERT_EQ(ENOSPC, errno);
}
-TEST(io, WriteFdExactly_string) {
+POSIX_TEST(io, WriteFdExactly_string) {
const char str[] = "Foobar";
TemporaryFile tf;
ASSERT_NE(-1, tf.fd);
@@ -137,7 +143,7 @@
EXPECT_STREQ(str, s.c_str());
}
-TEST(io, WriteFdFmt) {
+POSIX_TEST(io, WriteFdFmt) {
TemporaryFile tf;
ASSERT_NE(-1, tf.fd);
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 0c5be84..b18d574 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -1656,6 +1656,11 @@
else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
int exec_in = !strcmp(argv[0], "exec-in");
+ if (argc < 2) {
+ fprintf(stderr, "Usage: adb %s command\n", argv[0]);
+ return 1;
+ }
+
std::string cmd = "exec:";
cmd += argv[1];
argc -= 2;
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index 4721e2f..7f40b96 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -43,24 +43,15 @@
static const char* root_seclabel = nullptr;
-static void drop_capabilities_bounding_set_if_needed() {
-#ifdef ALLOW_ADBD_ROOT
+static void drop_capabilities_bounding_set_if_needed(struct minijail *j) {
+#if defined(ALLOW_ADBD_ROOT)
char value[PROPERTY_VALUE_MAX];
property_get("ro.debuggable", value, "");
if (strcmp(value, "1") == 0) {
return;
}
#endif
- for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
- if (i == CAP_SETUID || i == CAP_SETGID) {
- // CAP_SETUID CAP_SETGID needed by /system/bin/run-as
- continue;
- }
-
- if (prctl(PR_CAPBSET_DROP, i, 0, 0, 0) == -1) {
- PLOG(FATAL) << "Could not drop capabilities";
- }
- }
+ minijail_capbset_drop(j, CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID));
}
static bool should_drop_privileges() {
@@ -131,7 +122,7 @@
// Don't listen on a port (default 5037) if running in secure mode.
// Don't run as root if running in secure mode.
if (should_drop_privileges()) {
- drop_capabilities_bounding_set_if_needed();
+ drop_capabilities_bounding_set_if_needed(jail.get());
minijail_change_gid(jail.get(), AID_SHELL);
minijail_change_uid(jail.get(), AID_SHELL);
diff --git a/adb/shell_service.cpp b/adb/shell_service.cpp
index ce10708..3eeed34 100644
--- a/adb/shell_service.cpp
+++ b/adb/shell_service.cpp
@@ -246,7 +246,7 @@
char** current = environ;
while (char* env_cstr = *current++) {
std::string env_string = env_cstr;
- char* delimiter = strchr(env_string.c_str(), '=');
+ char* delimiter = strchr(&env_string[0], '=');
// Drop any values that don't contain '='.
if (delimiter) {
diff --git a/adb/socket.h b/adb/socket.h
index 9eb1b19..4acdf4a 100644
--- a/adb/socket.h
+++ b/adb/socket.h
@@ -118,7 +118,7 @@
namespace internal {
#if ADB_HOST
-char* skip_host_serial(const char* service);
+char* skip_host_serial(char* service);
#endif
} // namespace internal
diff --git a/adb/socket_test.cpp b/adb/socket_test.cpp
index 5cbef6d..20a3bbb 100644
--- a/adb/socket_test.cpp
+++ b/adb/socket_test.cpp
@@ -275,8 +275,8 @@
// Checks that skip_host_serial(serial) returns a pointer to the part of |serial| which matches
// |expected|, otherwise logs the failure to gtest.
-void VerifySkipHostSerial(const std::string& serial, const char* expected) {
- const char* result = internal::skip_host_serial(serial.c_str());
+void VerifySkipHostSerial(std::string serial, const char* expected) {
+ char* result = internal::skip_host_serial(&serial[0]);
if (expected == nullptr) {
EXPECT_EQ(nullptr, result);
} else {
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index c083ee1..aecaba2 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -634,7 +634,7 @@
// Where <port> must be a base-10 number and <prefix> may be any of {usb,product,model,device}.
//
// The returned pointer will point to the ':' just before <command>, or nullptr if not found.
-char* skip_host_serial(const char* service) {
+char* skip_host_serial(char* service) {
static const std::vector<std::string>& prefixes =
*(new std::vector<std::string>{"usb:", "product:", "model:", "device:"});
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 413b362..c31f655 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -295,20 +295,12 @@
transport_unref(t);
}
-static void kick_transport_locked(atransport* t) {
- CHECK(t != nullptr);
- if (!t->kicked) {
- t->kicked = true;
- t->kick(t);
- }
-}
-
void kick_transport(atransport* t) {
adb_mutex_lock(&transport_lock);
// As kick_transport() can be called from threads without guarantee that t is valid,
// check if the transport is in transport_list first.
if (std::find(transport_list.begin(), transport_list.end(), t) != transport_list.end()) {
- kick_transport_locked(t);
+ t->Kick();
}
adb_mutex_unlock(&transport_lock);
}
@@ -621,7 +613,6 @@
t->ref_count--;
if (t->ref_count == 0) {
D("transport: %s unref (kicking and closing)", t->serial);
- kick_transport_locked(t);
t->close(t);
remove_transport(t);
} else {
@@ -748,6 +739,14 @@
return result;
}
+void atransport::Kick() {
+ if (!kicked_) {
+ kicked_ = true;
+ CHECK(kick_func_ != nullptr);
+ kick_func_(this);
+ }
+}
+
const std::string atransport::connection_state_name() const {
switch (connection_state) {
case kCsOffline: return "offline";
@@ -926,10 +925,7 @@
void close_usb_devices() {
adb_mutex_lock(&transport_lock);
for (const auto& t : transport_list) {
- if (!t->kicked) {
- t->kicked = 1;
- t->kick(t);
- }
+ t->Kick();
}
adb_mutex_unlock(&transport_lock);
}
@@ -1000,7 +996,7 @@
// the read_transport thread will notify the main thread to make this transport
// offline. Then the main thread will notify the write_transport thread to exit.
// Finally, this transport will be closed and freed in the main thread.
- kick_transport_locked(t);
+ t->Kick();
}
}
adb_mutex_unlock(&transport_lock);
diff --git a/adb/transport.h b/adb/transport.h
index 5857249..35d7b50 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -60,7 +60,13 @@
int (*read_from_remote)(apacket* p, atransport* t) = nullptr;
int (*write_to_remote)(apacket* p, atransport* t) = nullptr;
void (*close)(atransport* t) = nullptr;
- void (*kick)(atransport* t) = nullptr;
+ void SetKickFunction(void (*kick_func)(atransport*)) {
+ kick_func_ = kick_func;
+ }
+ bool IsKicked() {
+ return kicked_;
+ }
+ void Kick();
int fd = -1;
int transport_socket = -1;
@@ -82,7 +88,6 @@
char* device = nullptr;
char* devpath = nullptr;
int adb_port = -1; // Use for emulators (local transport)
- bool kicked = false;
void* key = nullptr;
unsigned char token[TOKEN_SIZE] = {};
@@ -123,6 +128,9 @@
bool MatchesTarget(const std::string& target) const;
private:
+ bool kicked_ = false;
+ void (*kick_func_)(atransport*) = nullptr;
+
// A set of features transmitted in the banner with the initial connection.
// This is stored in the banner as 'features=feature0,feature1,etc'.
FeatureSet features_;
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index f6c9df4..4121f47 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -388,7 +388,7 @@
{
int fail = 0;
- t->kick = remote_kick;
+ t->SetKickFunction(remote_kick);
t->close = remote_close;
t->read_from_remote = remote_read;
t->write_to_remote = remote_write;
diff --git a/adb/transport_test.cpp b/adb/transport_test.cpp
index 2028ecc..a6db07a 100644
--- a/adb/transport_test.cpp
+++ b/adb/transport_test.cpp
@@ -20,47 +20,6 @@
#include "adb.h"
-class TestTransport : public atransport {
-public:
- bool operator==(const atransport& rhs) const {
- EXPECT_EQ(read_from_remote, rhs.read_from_remote);
- EXPECT_EQ(write_to_remote, rhs.write_to_remote);
- EXPECT_EQ(close, rhs.close);
- EXPECT_EQ(kick, rhs.kick);
-
- EXPECT_EQ(fd, rhs.fd);
- EXPECT_EQ(transport_socket, rhs.transport_socket);
-
- EXPECT_EQ(
- 0, memcmp(&transport_fde, &rhs.transport_fde, sizeof(fdevent)));
-
- EXPECT_EQ(ref_count, rhs.ref_count);
- EXPECT_EQ(sync_token, rhs.sync_token);
- EXPECT_EQ(connection_state, rhs.connection_state);
- EXPECT_EQ(online, rhs.online);
- EXPECT_EQ(type, rhs.type);
-
- EXPECT_EQ(usb, rhs.usb);
- EXPECT_EQ(sfd, rhs.sfd);
-
- EXPECT_EQ(serial, rhs.serial);
- EXPECT_EQ(product, rhs.product);
- EXPECT_EQ(model, rhs.model);
- EXPECT_EQ(device, rhs.device);
- EXPECT_EQ(devpath, rhs.devpath);
- EXPECT_EQ(adb_port, rhs.adb_port);
- EXPECT_EQ(kicked, rhs.kicked);
-
- EXPECT_EQ(key, rhs.key);
- EXPECT_EQ(0, memcmp(token, rhs.token, TOKEN_SIZE));
- EXPECT_EQ(failed_auth_attempts, rhs.failed_auth_attempts);
-
- EXPECT_EQ(features(), rhs.features());
-
- return true;
- }
-};
-
class TransportSetup {
public:
TransportSetup() {
@@ -83,35 +42,19 @@
static TransportSetup g_TransportSetup;
TEST(transport, kick_transport) {
- TestTransport t;
-
+ atransport t;
+ static size_t kick_count;
+ kick_count = 0;
// Mutate some member so we can test that the function is run.
- t.kick = [](atransport* trans) { trans->fd = 42; };
-
- TestTransport expected;
- expected.kick = t.kick;
- expected.fd = 42;
- expected.kicked = 1;
-
- kick_transport(&t);
- ASSERT_EQ(42, t.fd);
- ASSERT_EQ(1, t.kicked);
- ASSERT_EQ(expected, t);
-}
-
-TEST(transport, kick_transport_already_kicked) {
- // Ensure that the transport is not modified if the transport has already been
- // kicked.
- TestTransport t;
- t.kicked = 1;
- t.kick = [](atransport*) { FAIL() << "Kick should not have been called"; };
-
- TestTransport expected;
- expected.kicked = 1;
- expected.kick = t.kick;
-
- kick_transport(&t);
- ASSERT_EQ(expected, t);
+ t.SetKickFunction([](atransport* trans) { kick_count++; });
+ ASSERT_FALSE(t.IsKicked());
+ t.Kick();
+ ASSERT_TRUE(t.IsKicked());
+ ASSERT_EQ(1u, kick_count);
+ // A transport can only be kicked once.
+ t.Kick();
+ ASSERT_TRUE(t.IsKicked());
+ ASSERT_EQ(1u, kick_count);
}
static void DisconnectFunc(void* arg, atransport*) {
diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp
index 263f9e7..d05d928 100644
--- a/adb/transport_usb.cpp
+++ b/adb/transport_usb.cpp
@@ -84,7 +84,7 @@
{
D("transport: usb");
t->close = remote_close;
- t->kick = remote_kick;
+ t->SetKickFunction(remote_kick);
t->read_from_remote = remote_read;
t->write_to_remote = remote_write;
t->sync_token = 1;
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index c863ed2..0ba6b4b 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -31,6 +31,9 @@
#include <unistd.h>
#include <algorithm>
+#include <atomic>
+
+#include <android-base/logging.h>
#include "adb.h"
#include "transport.h"
@@ -49,14 +52,19 @@
#define cpu_to_le16(x) htole16(x)
#define cpu_to_le32(x) htole32(x)
+static int dummy_fd = -1;
+
struct usb_handle
{
adb_cond_t notify;
adb_mutex_t lock;
+ bool open_new_connection;
+ std::atomic<bool> kicked;
int (*write)(usb_handle *h, const void *data, int len);
int (*read)(usb_handle *h, void *data, int len);
void (*kick)(usb_handle *h);
+ void (*close)(usb_handle *h);
// Legacy f_adb
int fd;
@@ -241,8 +249,10 @@
while (true) {
// wait until the USB device needs opening
adb_mutex_lock(&usb->lock);
- while (usb->fd != -1)
+ while (!usb->open_new_connection) {
adb_cond_wait(&usb->notify, &usb->lock);
+ }
+ usb->open_new_connection = false;
adb_mutex_unlock(&usb->lock);
D("[ usb_thread - opening device ]");
@@ -281,6 +291,10 @@
h->fd, n, errno, strerror(errno));
return -1;
}
+ if (h->kicked) {
+ D("usb_adb_write finished due to kicked");
+ return -1;
+ }
D("[ done fd=%d ]", h->fd);
return 0;
}
@@ -299,6 +313,10 @@
h->fd, n, errno, strerror(errno));
return -1;
}
+ if (h->kicked) {
+ D("usb_adb_read finished due to kicked");
+ return -1;
+ }
len -= n;
data = ((char*)data) + n;
}
@@ -306,14 +324,23 @@
return 0;
}
-static void usb_adb_kick(usb_handle *h)
-{
+static void usb_adb_kick(usb_handle *h) {
D("usb_kick");
- adb_mutex_lock(&h->lock);
- unix_close(h->fd);
- h->fd = -1;
+ // Other threads may be calling usb_adb_read/usb_adb_write at the same time.
+ // If we close h->fd, the file descriptor will be reused to open other files,
+ // and the read/write thread may operate on the wrong file. So instead
+ // we set the kicked flag and reopen h->fd to a dummy file here. After read/write
+ // threads finish, we close h->fd in usb_adb_close().
+ h->kicked = true;
+ TEMP_FAILURE_RETRY(dup2(dummy_fd, h->fd));
+}
- // notify usb_adb_open_thread that we are disconnected
+static void usb_adb_close(usb_handle *h) {
+ h->kicked = false;
+ adb_close(h->fd);
+ // Notify usb_adb_open_thread to open a new connection.
+ adb_mutex_lock(&h->lock);
+ h->open_new_connection = true;
adb_cond_signal(&h->notify);
adb_mutex_unlock(&h->lock);
}
@@ -326,8 +353,11 @@
h->write = usb_adb_write;
h->read = usb_adb_read;
h->kick = usb_adb_kick;
+ h->close = usb_adb_close;
+ h->kicked = false;
h->fd = -1;
+ h->open_new_connection = true;
adb_cond_init(&h->notify, 0);
adb_mutex_init(&h->lock, 0);
@@ -350,7 +380,7 @@
}
-static void init_functionfs(struct usb_handle *h)
+static bool init_functionfs(struct usb_handle *h)
{
ssize_t ret;
struct desc_v1 v1_descriptor;
@@ -413,7 +443,7 @@
goto err;
}
- return;
+ return true;
err:
if (h->bulk_in > 0) {
@@ -428,7 +458,7 @@
adb_close(h->control);
h->control = -1;
}
- return;
+ return false;
}
static void usb_ffs_open_thread(void* x) {
@@ -439,16 +469,16 @@
while (true) {
// wait until the USB device needs opening
adb_mutex_lock(&usb->lock);
- while (usb->control != -1 && usb->bulk_in != -1 && usb->bulk_out != -1)
+ while (!usb->open_new_connection) {
adb_cond_wait(&usb->notify, &usb->lock);
+ }
+ usb->open_new_connection = false;
adb_mutex_unlock(&usb->lock);
while (true) {
- init_functionfs(usb);
-
- if (usb->control >= 0 && usb->bulk_in >= 0 && usb->bulk_out >= 0)
+ if (init_functionfs(usb)) {
break;
-
+ }
adb_sleep_ms(1000);
}
property_set("sys.usb.ffs.ready", "1");
@@ -513,16 +543,22 @@
D("[ kick: sink (fd=%d) clear halt failed (%d) ]", h->bulk_out, errno);
}
- adb_mutex_lock(&h->lock);
-
// don't close ep0 here, since we may not need to reinitialize it with
// the same descriptors again. if however ep1/ep2 fail to re-open in
// init_functionfs, only then would we close and open ep0 again.
+ // Ditto the comment in usb_adb_kick.
+ h->kicked = true;
+ TEMP_FAILURE_RETRY(dup2(dummy_fd, h->bulk_out));
+ TEMP_FAILURE_RETRY(dup2(dummy_fd, h->bulk_in));
+}
+
+static void usb_ffs_close(usb_handle *h) {
+ h->kicked = false;
adb_close(h->bulk_out);
adb_close(h->bulk_in);
- h->bulk_out = h->bulk_in = -1;
-
- // notify usb_ffs_open_thread that we are disconnected
+ // Notify usb_adb_open_thread to open a new connection.
+ adb_mutex_lock(&h->lock);
+ h->open_new_connection = true;
adb_cond_signal(&h->notify);
adb_mutex_unlock(&h->lock);
}
@@ -537,10 +573,13 @@
h->write = usb_ffs_write;
h->read = usb_ffs_read;
h->kick = usb_ffs_kick;
+ h->close = usb_ffs_close;
+ h->kicked = false;
h->control = -1;
h->bulk_out = -1;
h->bulk_out = -1;
+ h->open_new_connection = true;
adb_cond_init(&h->notify, 0);
adb_mutex_init(&h->lock, 0);
@@ -552,6 +591,8 @@
void usb_init()
{
+ dummy_fd = adb_open("/dev/null", O_WRONLY);
+ CHECK_NE(dummy_fd, -1);
if (access(USB_FFS_ADB_EP0, F_OK) == 0)
usb_ffs_init();
else
@@ -569,6 +610,7 @@
}
int usb_close(usb_handle *h)
{
+ h->close(h);
return 0;
}
diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp
index 54d4c6c..ddde454 100644
--- a/adb/usb_osx.cpp
+++ b/adb/usb_osx.cpp
@@ -29,86 +29,96 @@
#include <inttypes.h>
#include <stdio.h>
+#include <atomic>
+#include <memory>
+#include <mutex>
+#include <vector>
+
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include "adb.h"
#include "transport.h"
-#define DBG D
-
-// There's no strerror equivalent for the errors returned by IOKit.
-// https://developer.apple.com/library/mac/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_Handling_Errors/AH_Handling_Errors.html
-// Search the web for "IOReturn.h" to find a complete up to date list.
-
-static IONotificationPortRef notificationPort = 0;
-static io_iterator_t notificationIterator;
-
struct usb_handle
{
UInt8 bulkIn;
UInt8 bulkOut;
IOUSBInterfaceInterface190** interface;
- io_object_t usbNotification;
unsigned int zero_mask;
+
+ // For garbage collecting disconnected devices.
+ bool mark;
+ std::string devpath;
+ std::atomic<bool> dead;
+
+ usb_handle() : bulkIn(0), bulkOut(0), interface(nullptr),
+ zero_mask(0), mark(false), dead(false) {
+ }
};
-static CFRunLoopRef currentRunLoop = 0;
-static pthread_mutex_t start_lock;
-static pthread_cond_t start_cond;
+static std::atomic<bool> usb_inited_flag;
+static auto& g_usb_handles_mutex = *new std::mutex();
+static auto& g_usb_handles = *new std::vector<std::unique_ptr<usb_handle>>();
-static void AndroidInterfaceAdded(void *refCon, io_iterator_t iterator);
-static void AndroidInterfaceNotify(void *refCon, io_iterator_t iterator,
- natural_t messageType,
- void *messageArgument);
-static usb_handle* CheckInterface(IOUSBInterfaceInterface190 **iface,
- UInt16 vendor, UInt16 product);
-
-static int
-InitUSB()
-{
- CFMutableDictionaryRef matchingDict;
- CFRunLoopSourceRef runLoopSource;
-
- //* To set up asynchronous notifications, create a notification port and
- //* add its run loop event source to the program's run loop
- notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
- runLoopSource = IONotificationPortGetRunLoopSource(notificationPort);
- CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
-
- //* Create our matching dictionary to find the Android device's
- //* adb interface
- //* IOServiceAddMatchingNotification consumes the reference, so we do
- //* not need to release this
- matchingDict = IOServiceMatching(kIOUSBInterfaceClassName);
-
- if (!matchingDict) {
- LOG(ERROR) << "Couldn't create USB matching dictionary.";
- return -1;
+static bool IsKnownDevice(const std::string& devpath) {
+ std::lock_guard<std::mutex> lock_guard(g_usb_handles_mutex);
+ for (auto& usb : g_usb_handles) {
+ if (usb->devpath == devpath) {
+ // Set mark flag to indicate this device is still alive.
+ usb->mark = true;
+ return true;
+ }
}
+ return false;
+}
- //* We have to get notifications for all potential candidates and test them
- //* at connection time because the matching rules don't allow for a
- //* USB interface class of 0xff for class+subclass+protocol matches
- //* See https://developer.apple.com/library/mac/qa/qa1076/_index.html
- IOServiceAddMatchingNotification(
- notificationPort,
- kIOFirstMatchNotification,
- matchingDict,
- AndroidInterfaceAdded,
- NULL,
- ¬ificationIterator);
+static void usb_kick_locked(usb_handle* handle);
- //* Iterate over set of matching interfaces to access already-present
- //* devices and to arm the notification
- AndroidInterfaceAdded(NULL, notificationIterator);
+static void KickDisconnectedDevices() {
+ std::lock_guard<std::mutex> lock_guard(g_usb_handles_mutex);
+ for (auto& usb : g_usb_handles) {
+ if (!usb->mark) {
+ usb_kick_locked(usb.get());
+ } else {
+ usb->mark = false;
+ }
+ }
+}
- return 0;
+static void AddDevice(std::unique_ptr<usb_handle> handle) {
+ handle->mark = true;
+ std::lock_guard<std::mutex> lock(g_usb_handles_mutex);
+ g_usb_handles.push_back(std::move(handle));
+}
+
+static void AndroidInterfaceAdded(io_iterator_t iterator);
+static std::unique_ptr<usb_handle> CheckInterface(IOUSBInterfaceInterface190 **iface,
+ UInt16 vendor, UInt16 product);
+
+static bool FindUSBDevices() {
+ // Create the matching dictionary to find the Android device's adb interface.
+ CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBInterfaceClassName);
+ if (!matchingDict) {
+ LOG(ERROR) << "couldn't create USB matching dictionary";
+ return false;
+ }
+ // Create an iterator for all I/O Registry objects that match the dictionary.
+ io_iterator_t iter = 0;
+ kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
+ if (kr != KERN_SUCCESS) {
+ LOG(ERROR) << "failed to get matching services";
+ return false;
+ }
+ // Iterate over all matching objects.
+ AndroidInterfaceAdded(iter);
+ IOObjectRelease(iter);
+ return true;
}
static void
-AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
+AndroidInterfaceAdded(io_iterator_t iterator)
{
kern_return_t kr;
io_service_t usbDevice;
@@ -124,8 +134,7 @@
UInt16 product;
UInt8 serialIndex;
char serial[256];
- char devpathBuf[64];
- char *devpath = NULL;
+ std::string devpath;
while ((usbInterface = IOIteratorNext(iterator))) {
//* Create an intermediate interface plugin
@@ -199,9 +208,11 @@
kr = (*dev)->GetDeviceVendor(dev, &vendor);
kr = (*dev)->GetDeviceProduct(dev, &product);
kr = (*dev)->GetLocationID(dev, &locationId);
- if (kr == 0) {
- snprintf(devpathBuf, sizeof(devpathBuf), "usb:%" PRIu32 "X", locationId);
- devpath = devpathBuf;
+ if (kr == KERN_SUCCESS) {
+ devpath = android::base::StringPrintf("usb:%" PRIu32 "X", locationId);
+ if (IsKnownDevice(devpath)) {
+ continue;
+ }
}
kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex);
@@ -256,49 +267,29 @@
(*dev)->Release(dev);
- LOG(INFO) << android::base::StringPrintf("Found vid=%04x pid=%04x serial=%s\n",
+ VLOG(USB) << android::base::StringPrintf("Found vid=%04x pid=%04x serial=%s\n",
vendor, product, serial);
-
- usb_handle* handle = CheckInterface((IOUSBInterfaceInterface190**)iface,
- vendor, product);
- if (handle == NULL) {
- LOG(ERROR) << "Could not find device interface";
+ if (devpath.empty()) {
+ devpath = serial;
+ }
+ if (IsKnownDevice(devpath)) {
+ (*iface)->USBInterfaceClose(iface);
(*iface)->Release(iface);
continue;
}
- LOG(DEBUG) << "AndroidDeviceAdded calling register_usb_transport";
- register_usb_transport(handle, (serial[0] ? serial : NULL), devpath, 1);
-
- // Register for an interest notification of this device being removed.
- // Pass the reference to our private data as the refCon for the
- // notification.
- kr = IOServiceAddInterestNotification(notificationPort,
- usbInterface,
- kIOGeneralInterest,
- AndroidInterfaceNotify,
- handle,
- &handle->usbNotification);
-
- if (kIOReturnSuccess != kr) {
- LOG(ERROR) << "Unable to create interest notification (" << std::hex << kr << ")";
+ std::unique_ptr<usb_handle> handle = CheckInterface((IOUSBInterfaceInterface190**)iface,
+ vendor, product);
+ if (handle == nullptr) {
+ LOG(ERROR) << "Could not find device interface";
+ (*iface)->Release(iface);
+ continue;
}
- }
-}
-
-static void
-AndroidInterfaceNotify(void *refCon, io_service_t service, natural_t messageType, void *messageArgument)
-{
- usb_handle *handle = (usb_handle *)refCon;
-
- if (messageType == kIOMessageServiceIsTerminated) {
- if (!handle) {
- LOG(ERROR) << "NULL handle";
- return;
- }
- LOG(DEBUG) << "AndroidInterfaceNotify";
- IOObjectRelease(handle->usbNotification);
- usb_kick(handle);
+ handle->devpath = devpath;
+ usb_handle* handle_p = handle.get();
+ VLOG(USB) << "Add usb device " << serial;
+ AddDevice(std::move(handle));
+ register_usb_transport(handle_p, serial, devpath.c_str(), 1);
}
}
@@ -316,10 +307,10 @@
//* TODO: simplify this further since we only register to get ADB interface
//* subclass+protocol events
-static usb_handle*
+static std::unique_ptr<usb_handle>
CheckInterface(IOUSBInterfaceInterface190 **interface, UInt16 vendor, UInt16 product)
{
- usb_handle* handle;
+ std::unique_ptr<usb_handle> handle;
IOReturn kr;
UInt8 interfaceNumEndpoints, interfaceClass, interfaceSubClass, interfaceProtocol;
UInt8 endpoint;
@@ -353,8 +344,10 @@
goto err_bad_adb_interface;
}
- handle = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle)));
- if (handle == nullptr) goto err_bad_adb_interface;
+ handle.reset(new usb_handle);
+ if (handle == nullptr) {
+ goto err_bad_adb_interface;
+ }
//* Iterate over the endpoints for this interface and find the first
//* bulk in/out pipes available. These will be our read/write pipes.
@@ -392,39 +385,37 @@
return handle;
err_get_pipe_props:
- free(handle);
err_bad_adb_interface:
err_get_interface_class:
err_get_num_ep:
(*interface)->USBInterfaceClose(interface);
- return NULL;
+ return nullptr;
}
+std::mutex& operate_device_lock = *new std::mutex();
+
static void RunLoopThread(void* unused) {
adb_thread_setname("RunLoop");
- InitUSB();
- currentRunLoop = CFRunLoopGetCurrent();
-
- // Signal the parent that we are running
- adb_mutex_lock(&start_lock);
- adb_cond_signal(&start_cond);
- adb_mutex_unlock(&start_lock);
-
- CFRunLoopRun();
- currentRunLoop = 0;
-
- IOObjectRelease(notificationIterator);
- IONotificationPortDestroy(notificationPort);
-
- LOG(DEBUG) << "RunLoopThread done";
+ VLOG(USB) << "RunLoopThread started";
+ while (true) {
+ {
+ std::lock_guard<std::mutex> lock_guard(operate_device_lock);
+ FindUSBDevices();
+ KickDisconnectedDevices();
+ }
+ // Signal the parent that we are running
+ usb_inited_flag = true;
+ adb_sleep_ms(1000);
+ }
+ VLOG(USB) << "RunLoopThread done";
}
static void usb_cleanup() {
- LOG(DEBUG) << "usb_cleanup";
+ VLOG(USB) << "usb_cleanup";
+ // Wait until usb operations in RunLoopThread finish, and prevent further operations.
+ operate_device_lock.lock();
close_usb_devices();
- if (currentRunLoop)
- CFRunLoopStop(currentRunLoop);
}
void usb_init() {
@@ -432,20 +423,16 @@
if (!initialized) {
atexit(usb_cleanup);
- adb_mutex_init(&start_lock, NULL);
- adb_cond_init(&start_cond, NULL);
+ usb_inited_flag = false;
if (!adb_thread_create(RunLoopThread, nullptr)) {
fatal_errno("cannot create RunLoop thread");
}
// Wait for initialization to finish
- adb_mutex_lock(&start_lock);
- adb_cond_wait(&start_cond, &start_lock);
- adb_mutex_unlock(&start_lock);
-
- adb_mutex_destroy(&start_lock);
- adb_cond_destroy(&start_cond);
+ while (!usb_inited_flag) {
+ adb_sleep_ms(100);
+ }
initialized = true;
}
@@ -458,7 +445,7 @@
if (!len)
return 0;
- if (!handle)
+ if (!handle || handle->dead)
return -1;
if (NULL == handle->interface) {
@@ -499,7 +486,7 @@
return 0;
}
- if (!handle) {
+ if (!handle || handle->dead) {
return -1;
}
@@ -532,20 +519,33 @@
int usb_close(usb_handle *handle)
{
+ std::lock_guard<std::mutex> lock(g_usb_handles_mutex);
+ for (auto it = g_usb_handles.begin(); it != g_usb_handles.end(); ++it) {
+ if ((*it).get() == handle) {
+ g_usb_handles.erase(it);
+ break;
+ }
+ }
return 0;
}
-void usb_kick(usb_handle *handle)
+static void usb_kick_locked(usb_handle *handle)
{
LOG(INFO) << "Kicking handle";
/* release the interface */
if (!handle)
return;
- if (handle->interface)
+ if (!handle->dead)
{
+ handle->dead = true;
(*handle->interface)->USBInterfaceClose(handle->interface);
(*handle->interface)->Release(handle->interface);
- handle->interface = 0;
}
}
+
+void usb_kick(usb_handle *handle) {
+ // Use the lock to avoid multiple thread kicking the device at the same time.
+ std::lock_guard<std::mutex> lock_guard(g_usb_handles_mutex);
+ usb_kick_locked(handle);
+}
diff --git a/base/include/android-base/errors.h b/base/include/android-base/errors.h
index ca621fa..04c299c 100644
--- a/base/include/android-base/errors.h
+++ b/base/include/android-base/errors.h
@@ -27,8 +27,8 @@
// special handling to get the error string. Refer to Microsoft documentation
// to determine which error code to check for each function.
-#ifndef BASE_ERRORS_H
-#define BASE_ERRORS_H
+#ifndef ANDROID_BASE_ERRORS_H
+#define ANDROID_BASE_ERRORS_H
#include <string>
@@ -43,4 +43,4 @@
} // namespace base
} // namespace android
-#endif // BASE_ERRORS_H
+#endif // ANDROID_BASE_ERRORS_H
diff --git a/base/include/android-base/file.h b/base/include/android-base/file.h
index 5342d98..aa18ea7 100644
--- a/base/include/android-base/file.h
+++ b/base/include/android-base/file.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef BASE_FILE_H
-#define BASE_FILE_H
+#ifndef ANDROID_BASE_FILE_H
+#define ANDROID_BASE_FILE_H
#include <sys/stat.h>
#include <string>
@@ -46,4 +46,4 @@
} // namespace base
} // namespace android
-#endif // BASE_FILE_H
+#endif // ANDROID_BASE_FILE_H
diff --git a/base/include/android-base/logging.h b/base/include/android-base/logging.h
index c82f858..b86c232 100644
--- a/base/include/android-base/logging.h
+++ b/base/include/android-base/logging.h
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#ifndef BASE_LOGGING_H
-#define BASE_LOGGING_H
+
+#ifndef ANDROID_BASE_LOGGING_H
+#define ANDROID_BASE_LOGGING_H
// NOTE: For Windows, you must include logging.h after windows.h to allow the
// following code to suppress the evil ERROR macro:
@@ -146,6 +147,14 @@
#define UNIMPLEMENTED(level) \
LOG(level) << __PRETTY_FUNCTION__ << " unimplemented "
+#ifdef __clang_analyzer__
+// ClangL static analyzer does not see the conditional statement inside
+// LogMessage's destructor that will abort on FATAL severity.
+#define ABORT_AFTER_LOG_FATAL for (;;abort())
+#else
+#define ABORT_AFTER_LOG_FATAL
+#endif
+
// Check whether condition x holds and LOG(FATAL) if not. The value of the
// expression x is only evaluated once. Extra logging can be appended using <<
// after. For example:
@@ -154,6 +163,7 @@
// "Check failed: false == true".
#define CHECK(x) \
LIKELY((x)) || \
+ ABORT_AFTER_LOG_FATAL \
::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \
::android::base::FATAL, -1).stream() \
<< "Check failed: " #x << " "
@@ -163,6 +173,7 @@
for (auto _values = ::android::base::MakeEagerEvaluator(LHS, RHS); \
UNLIKELY(!(_values.lhs OP _values.rhs)); \
/* empty */) \
+ ABORT_AFTER_LOG_FATAL \
::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \
::android::base::FATAL, -1).stream() \
<< "Check failed: " << #LHS << " " << #OP << " " << #RHS \
@@ -186,6 +197,7 @@
if (LIKELY((strcmp(s1, s2) == 0) == sense)) \
; \
else \
+ ABORT_AFTER_LOG_FATAL \
LOG(FATAL) << "Check failed: " \
<< "\"" << s1 << "\"" \
<< (sense ? " == " : " != ") << "\"" << s2 << "\""
@@ -200,6 +212,7 @@
int rc = call args; \
if (rc != 0) { \
errno = rc; \
+ ABORT_AFTER_LOG_FATAL \
PLOG(FATAL) << #call << " failed for " << what; \
} \
} while (false)
@@ -334,4 +347,4 @@
} // namespace base
} // namespace android
-#endif // BASE_LOGGING_H
+#endif // ANDROID_BASE_LOGGING_H
diff --git a/base/include/android-base/macros.h b/base/include/android-base/macros.h
index b1ce7c6..299ec35 100644
--- a/base/include/android-base/macros.h
+++ b/base/include/android-base/macros.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef UTILS_MACROS_H
-#define UTILS_MACROS_H
+#ifndef ANDROID_BASE_MACROS_H
+#define ANDROID_BASE_MACROS_H
#include <stddef.h> // for size_t
#include <unistd.h> // for TEMP_FAILURE_RETRY
@@ -123,8 +123,11 @@
((sizeof(a) / sizeof(*(a))) / \
static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
-#define LIKELY(x) __builtin_expect((x), true)
-#define UNLIKELY(x) __builtin_expect((x), false)
+// Changing this definition will cause you a lot of pain. A majority of
+// vendor code defines LIKELY and UNLIKELY this way, and includes
+// this header through an indirect path.
+#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
+#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
#define WARN_UNUSED __attribute__((warn_unused_result))
@@ -185,4 +188,4 @@
} while (0)
#endif
-#endif // UTILS_MACROS_H
+#endif // ANDROID_BASE_MACROS_H
diff --git a/base/include/android-base/memory.h b/base/include/android-base/memory.h
index 882582f..3a2f8fa 100644
--- a/base/include/android-base/memory.h
+++ b/base/include/android-base/memory.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef BASE_MEMORY_H
-#define BASE_MEMORY_H
+#ifndef ANDROID_BASE_MEMORY_H
+#define ANDROID_BASE_MEMORY_H
namespace android {
namespace base {
@@ -44,4 +44,4 @@
} // namespace base
} // namespace android
-#endif // BASE_MEMORY_H
+#endif // ANDROID_BASE_MEMORY_H
diff --git a/base/include/android-base/parseint.h b/base/include/android-base/parseint.h
index 0543795..ed75e2d 100644
--- a/base/include/android-base/parseint.h
+++ b/base/include/android-base/parseint.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef BASE_PARSEINT_H
-#define BASE_PARSEINT_H
+#ifndef ANDROID_BASE_PARSEINT_H
+#define ANDROID_BASE_PARSEINT_H
#include <errno.h>
#include <stdlib.h>
@@ -70,4 +70,4 @@
} // namespace base
} // namespace android
-#endif // BASE_PARSEINT_H
+#endif // ANDROID_BASE_PARSEINT_H
diff --git a/base/include/android-base/parsenetaddress.h b/base/include/android-base/parsenetaddress.h
index 2de5ac9..b4ac025 100644
--- a/base/include/android-base/parsenetaddress.h
+++ b/base/include/android-base/parsenetaddress.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef BASE_PARSENETADDRESS_H
-#define BASE_PARSENETADDRESS_H
+#ifndef ANDROID_BASE_PARSENETADDRESS_H
+#define ANDROID_BASE_PARSENETADDRESS_H
#include <string>
@@ -35,4 +35,4 @@
} // namespace base
} // namespace android
-#endif // BASE_PARSENETADDRESS_H
+#endif // ANDROID_BASE_PARSENETADDRESS_H
diff --git a/base/include/android-base/stringprintf.h b/base/include/android-base/stringprintf.h
index d68af87..cf666ab 100644
--- a/base/include/android-base/stringprintf.h
+++ b/base/include/android-base/stringprintf.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef BASE_STRINGPRINTF_H
-#define BASE_STRINGPRINTF_H
+#ifndef ANDROID_BASE_STRINGPRINTF_H
+#define ANDROID_BASE_STRINGPRINTF_H
#include <stdarg.h>
#include <string>
@@ -53,4 +53,4 @@
} // namespace base
} // namespace android
-#endif // BASE_STRINGPRINTF_H
+#endif // ANDROID_BASE_STRINGPRINTF_H
diff --git a/base/include/android-base/strings.h b/base/include/android-base/strings.h
index 20da144..69781cd 100644
--- a/base/include/android-base/strings.h
+++ b/base/include/android-base/strings.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef BASE_STRINGS_H
-#define BASE_STRINGS_H
+#ifndef ANDROID_BASE_STRINGS_H
+#define ANDROID_BASE_STRINGS_H
#include <sstream>
#include <string>
@@ -65,4 +65,4 @@
} // namespace base
} // namespace android
-#endif // BASE_STRINGS_H
+#endif // ANDROID_BASE_STRINGS_H
diff --git a/base/include/android-base/test_utils.h b/base/include/android-base/test_utils.h
index 3f6872c..4ea3c8e 100644
--- a/base/include/android-base/test_utils.h
+++ b/base/include/android-base/test_utils.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef TEST_UTILS_H
-#define TEST_UTILS_H
+#ifndef ANDROID_BASE_TEST_UTILS_H
+#define ANDROID_BASE_TEST_UTILS_H
#include <string>
@@ -48,4 +48,4 @@
DISALLOW_COPY_AND_ASSIGN(TemporaryDir);
};
-#endif // TEST_UTILS_H
+#endif // ANDROID_BASE_TEST_UTILS_H
diff --git a/base/include/android-base/thread_annotations.h b/base/include/android-base/thread_annotations.h
index 90979df..2422102 100644
--- a/base/include/android-base/thread_annotations.h
+++ b/base/include/android-base/thread_annotations.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef UTILS_THREAD_ANNOTATIONS_H
-#define UTILS_THREAD_ANNOTATIONS_H
+#ifndef ANDROID_BASE_THREAD_ANNOTATIONS_H
+#define ANDROID_BASE_THREAD_ANNOTATIONS_H
#if defined(__SUPPORT_TS_ANNOTATION__) || defined(__clang__)
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
@@ -80,4 +80,4 @@
#define NO_THREAD_SAFETY_ANALYSIS \
THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
-#endif // UTILS_THREAD_ANNOTATIONS_H
+#endif // ANDROID_BASE_THREAD_ANNOTATIONS_H
diff --git a/base/include/android-base/unique_fd.h b/base/include/android-base/unique_fd.h
index d3b27ca..ab41c55 100644
--- a/base/include/android-base/unique_fd.h
+++ b/base/include/android-base/unique_fd.h
@@ -19,20 +19,23 @@
#include <unistd.h>
-#include <android-base/macros.h>
+// DO NOT INCLUDE OTHER LIBBASE HEADERS!
+// This file gets used in libbinder, and libbinder is used everywhere.
+// Including other headers from libbase frequently results in inclusion of
+// android-base/macros.h, which causes macro collisions.
-/* Container for a file descriptor that automatically closes the descriptor as
- * it goes out of scope.
- *
- * unique_fd ufd(open("/some/path", "r"));
- *
- * if (ufd.get() < 0) // invalid descriptor
- * return error;
- *
- * // Do something useful
- *
- * return 0; // descriptor is closed here
- */
+// Container for a file descriptor that automatically closes the descriptor as
+// it goes out of scope.
+//
+// unique_fd ufd(open("/some/path", "r"));
+// if (ufd.get() == -1) return error;
+//
+// // Do something useful, possibly including 'return'.
+//
+// return 0; // Descriptor is closed for you.
+//
+// unique_fd is also known as ScopedFd/ScopedFD/scoped_fd; mentioned here to help
+// you find this class if you're searching for one of those names.
namespace android {
namespace base {
@@ -44,14 +47,18 @@
~unique_fd() { clear(); }
unique_fd(unique_fd&& other) : value_(other.release()) {}
- unique_fd& operator = (unique_fd&& s) {
+ unique_fd& operator=(unique_fd&& s) {
reset(s.release());
return *this;
}
void reset(int new_value) {
- if (value_ >= 0)
+ if (value_ != -1) {
+ // Even if close(2) fails with EINTR, the fd will have been closed.
+ // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone else's fd.
+ // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
close(value_);
+ }
value_ = new_value;
}
@@ -60,8 +67,9 @@
}
int get() const { return value_; }
+ operator int() const { return get(); }
- int release() {
+ int release() __attribute__((warn_unused_result)) {
int ret = value_;
value_ = -1;
return ret;
@@ -70,10 +78,11 @@
private:
int value_;
- DISALLOW_COPY_AND_ASSIGN(unique_fd);
+ unique_fd(const unique_fd&);
+ void operator=(const unique_fd&);
};
} // namespace base
} // namespace android
-#endif // ANDROID_BASE_UNIQUE_FD_H
+#endif // ANDROID_BASE_UNIQUE_FD_H
diff --git a/base/include/android-base/utf8.h b/base/include/android-base/utf8.h
index 3b0ed0a..2d5a6f6 100755
--- a/base/include/android-base/utf8.h
+++ b/base/include/android-base/utf8.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef BASE_UTF8_H
-#define BASE_UTF8_H
+#ifndef ANDROID_BASE_UTF8_H
+#define ANDROID_BASE_UTF8_H
#ifdef _WIN32
#include <string>
@@ -84,4 +84,4 @@
} // namespace base
} // namespace android
-#endif // BASE_UTF8_H
+#endif // ANDROID_BASE_UTF8_H
diff --git a/base/test_utils.cpp b/base/test_utils.cpp
index 337ba7c..635af6c 100644
--- a/base/test_utils.cpp
+++ b/base/test_utils.cpp
@@ -16,7 +16,6 @@
#include "android-base/logging.h"
#include "android-base/test_utils.h"
-#include "utils/Compat.h" // For OS_PATH_SEPARATOR.
#include <fcntl.h>
#include <stdio.h>
@@ -27,6 +26,9 @@
#if defined(_WIN32)
#include <windows.h>
#include <direct.h>
+#define OS_PATH_SEPARATOR '\\'
+#else
+#define OS_PATH_SEPARATOR '/'
#endif
#include <string>
diff --git a/bootstat/boot_event_record_store_test.cpp b/bootstat/boot_event_record_store_test.cpp
index b7dd9ba..01c2cc1 100644
--- a/bootstat/boot_event_record_store_test.cpp
+++ b/bootstat/boot_event_record_store_test.cpp
@@ -41,7 +41,7 @@
// the value of the record.
bool CreateEmptyBootEventRecord(const std::string& record_path, int32_t value) {
android::base::unique_fd record_fd(creat(record_path.c_str(), S_IRUSR | S_IWUSR));
- if (record_fd.get() == -1) {
+ if (record_fd == -1) {
return false;
}
@@ -49,7 +49,7 @@
// ensure the validity of the file mtime value, i.e., to check that the record
// file mtime values are not changed once set.
// TODO(jhawkins): Remove this block.
- if (!android::base::WriteStringToFd(std::to_string(value), record_fd.get())) {
+ if (!android::base::WriteStringToFd(std::to_string(value), record_fd)) {
return false;
}
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 08fc5af..7c1b7f3 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -48,6 +48,21 @@
}
}
+// Records the named boot |event| to the record store. If |value| is non-empty
+// and is a proper string representation of an integer value, the converted
+// integer value is associated with the boot event.
+void RecordBootEventFromCommandLine(
+ const std::string& event, const std::string& value_str) {
+ BootEventRecordStore boot_event_store;
+ if (!value_str.empty()) {
+ int32_t value = 0;
+ value = std::stoi(value_str);
+ boot_event_store.AddBootEventWithValue(event, value);
+ } else {
+ boot_event_store.AddBootEvent(event);
+ }
+}
+
void PrintBootEvents() {
printf("Boot events:\n");
printf("------------\n");
@@ -67,6 +82,7 @@
" -l, --log Log all metrics to logstorage\n"
" -p, --print Dump the boot event records to the console\n"
" -r, --record Record the timestamp of a named boot event\n"
+ " --value Optional value to associate with the boot event\n"
" --record_boot_reason Record the reason why the device booted\n"
" --record_time_since_factory_reset Record the time since the device was reset\n");
}
@@ -121,6 +137,30 @@
{"Reboot", 18},
{"rtc", 19},
{"edl", 20},
+ {"oem_pon1", 21},
+ {"oem_powerkey", 22},
+ {"oem_unknown_reset", 23},
+ {"srto: HWWDT reset SC", 24},
+ {"srto: HWWDT reset platform", 25},
+ {"srto: bootloader", 26},
+ {"srto: kernel panic", 27},
+ {"srto: kernel watchdog reset", 28},
+ {"srto: normal", 29},
+ {"srto: reboot", 30},
+ {"srto: reboot-bootloader", 31},
+ {"srto: security watchdog reset", 32},
+ {"srto: wakesrc", 33},
+ {"srto: watchdog", 34},
+ {"srto:1-1", 35},
+ {"srto:omap_hsmm", 36},
+ {"srto:phy0", 37},
+ {"srto:rtc0", 38},
+ {"srto:touchpad", 39},
+ {"watchdog", 40},
+ {"watchdogr", 41},
+ {"wdog_bark", 42},
+ {"wdog_bite", 43},
+ {"wdog_reset", 44},
};
// Converts a string value representing the reason the system booted to an
@@ -165,7 +205,19 @@
void RecordBootComplete() {
BootEventRecordStore boot_event_store;
BootEventRecordStore::BootEventRecord record;
+
time_t uptime = bootstat::ParseUptime();
+ time_t current_time_utc = time(nullptr);
+
+ if (boot_event_store.GetBootEvent("last_boot_time_utc", &record)) {
+ time_t last_boot_time_utc = record.second;
+ time_t time_since_last_boot = difftime(current_time_utc,
+ last_boot_time_utc);
+ boot_event_store.AddBootEventWithValue("time_since_last_boot",
+ time_since_last_boot);
+ }
+
+ boot_event_store.AddBootEventWithValue("last_boot_time_utc", current_time_utc);
// The boot_complete metric has two variants: boot_complete and
// ota_boot_complete. The latter signifies that the device is booting after
@@ -266,6 +318,7 @@
LOG(INFO) << "Service started: " << cmd_line;
int option_index = 0;
+ static const char value_str[] = "value";
static const char boot_complete_str[] = "record_boot_complete";
static const char boot_reason_str[] = "record_boot_reason";
static const char factory_reset_str[] = "record_time_since_factory_reset";
@@ -274,19 +327,26 @@
{ "log", no_argument, NULL, 'l' },
{ "print", no_argument, NULL, 'p' },
{ "record", required_argument, NULL, 'r' },
+ { value_str, required_argument, NULL, 0 },
{ boot_complete_str, no_argument, NULL, 0 },
{ boot_reason_str, no_argument, NULL, 0 },
{ factory_reset_str, no_argument, NULL, 0 },
{ NULL, 0, NULL, 0 }
};
+ std::string boot_event;
+ std::string value;
int opt = 0;
while ((opt = getopt_long(argc, argv, "hlpr:", long_options, &option_index)) != -1) {
switch (opt) {
// This case handles long options which have no single-character mapping.
case 0: {
const std::string option_name = long_options[option_index].name;
- if (option_name == boot_complete_str) {
+ if (option_name == value_str) {
+ // |optarg| is an external variable set by getopt representing
+ // the option argument.
+ value = optarg;
+ } else if (option_name == boot_complete_str) {
RecordBootComplete();
} else if (option_name == boot_reason_str) {
RecordBootReason();
@@ -316,10 +376,7 @@
case 'r': {
// |optarg| is an external variable set by getopt representing
// the option argument.
- const char* event = optarg;
-
- BootEventRecordStore boot_event_store;
- boot_event_store.AddBootEvent(event);
+ boot_event = optarg;
break;
}
@@ -335,5 +392,9 @@
}
}
+ if (!boot_event.empty()) {
+ RecordBootEventFromCommandLine(boot_event, value);
+ }
+
return 0;
}
diff --git a/crash_reporter/crash_collector.cc b/crash_reporter/crash_collector.cc
index b3fdcb4..d993576 100644
--- a/crash_reporter/crash_collector.cc
+++ b/crash_reporter/crash_collector.cc
@@ -36,6 +36,7 @@
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/key_value_store.h>
+#include <brillo/osrelease_reader.h>
#include <brillo/process.h>
namespace {
@@ -52,6 +53,11 @@
const char kUploadVarPrefix[] = "upload_var_";
const char kUploadFilePrefix[] = "upload_file_";
+// Product information keys in the /etc/os-release.d folder.
+static const char kBdkVersionKey[] = "bdk_version";
+static const char kProductIDKey[] = "product_id";
+static const char kProductVersionKey[] = "product_version";
+
// Normally this path is not used. Unfortunately, there are a few edge cases
// where we need this. Any process that runs as kDefaultUserName that crashes
// is consider a "user crash". That includes the initial Chrome browser that
@@ -183,7 +189,7 @@
return true;
}
-bool CrashCollector::GetCreatedCrashDirectoryByEuid(uid_t euid,
+bool CrashCollector::GetCreatedCrashDirectoryByEuid(uid_t euid __unused,
FilePath *crash_directory,
bool *out_of_capacity) {
if (out_of_capacity) *out_of_capacity = false;
@@ -384,14 +390,49 @@
const std::string &payload_path) {
int64_t payload_size = -1;
base::GetFileSize(FilePath(payload_path), &payload_size);
+
+ brillo::OsReleaseReader reader;
+ if (!forced_osreleased_directory_.empty()) {
+ reader.LoadTestingOnly(forced_osreleased_directory_);
+ } else {
+ reader.Load();
+ }
+ std::string bdk_version = "undefined";
+ std::string product_id = "undefined";
+ std::string product_version = "undefined";
+
+ if (!reader.GetString(kBdkVersionKey, &bdk_version)) {
+ LOG(ERROR) << "Could not read " << kBdkVersionKey
+ << " from /etc/os-release.d/";
+ }
+
+ if (!reader.GetString(kProductIDKey, &product_id)) {
+ LOG(ERROR) << "Could not read " << kProductIDKey
+ << " from /etc/os-release.d/";
+ }
+
+ if (!reader.GetString(kProductVersionKey, &product_version)) {
+ LOG(ERROR) << "Could not read " << kProductVersionKey
+ << " from /etc/os-release.d/";
+ }
+
std::string meta_data = StringPrintf("%sexec_name=%s\n"
"payload=%s\n"
"payload_size=%" PRId64 "\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
"done=1\n",
extra_metadata_.c_str(),
exec_name.c_str(),
payload_path.c_str(),
- payload_size);
+ payload_size,
+ kBdkVersionKey,
+ bdk_version.c_str(),
+ kProductIDKey,
+ product_id.c_str(),
+ kProductVersionKey,
+ product_version.c_str());
// We must use WriteNewFile instead of base::WriteFile as we
// do not want to write with root access to a symlink that an attacker
// might have created.
diff --git a/crash_reporter/crash_collector.h b/crash_reporter/crash_collector.h
index 24cbfb3..21b9198 100644
--- a/crash_reporter/crash_collector.h
+++ b/crash_reporter/crash_collector.h
@@ -84,6 +84,12 @@
forced_crash_directory_ = forced_directory;
}
+ // For testing, set the root directory to read etc/os-release.d properties
+ // from.
+ void ForceOsReleaseDDirectory(const base::FilePath &forced_directory) {
+ forced_osreleased_directory_ = forced_directory;
+ }
+
base::FilePath GetCrashDirectoryInfo(mode_t *mode,
uid_t *directory_owner,
gid_t *directory_group);
@@ -158,6 +164,7 @@
IsFeedbackAllowedFunction is_feedback_allowed_function_;
std::string extra_metadata_;
base::FilePath forced_crash_directory_;
+ base::FilePath forced_osreleased_directory_;
base::FilePath log_config_path_;
private:
diff --git a/crash_reporter/crash_collector_test.cc b/crash_reporter/crash_collector_test.cc
index 11c8c0d..a386cd1 100644
--- a/crash_reporter/crash_collector_test.cc
+++ b/crash_reporter/crash_collector_test.cc
@@ -74,10 +74,11 @@
TEST_F(CrashCollectorTest, WriteNewFile) {
FilePath test_file = test_dir_.path().Append("test_new");
const char kBuffer[] = "buffer";
- EXPECT_EQ(strlen(kBuffer),
- collector_.WriteNewFile(test_file,
- kBuffer,
- strlen(kBuffer)));
+ unsigned int numBytesWritten = collector_.WriteNewFile(
+ test_file,
+ kBuffer,
+ strlen(kBuffer));
+ EXPECT_EQ(strlen(kBuffer), numBytesWritten);
EXPECT_LT(collector_.WriteNewFile(test_file,
kBuffer,
strlen(kBuffer)), 0);
@@ -94,7 +95,7 @@
}
TEST_F(CrashCollectorTest, FormatDumpBasename) {
- struct tm tm = {0};
+ struct tm tm = {};
tm.tm_sec = 15;
tm.tm_min = 50;
tm.tm_hour = 13;
@@ -182,9 +183,26 @@
const char kMetaFileBasename[] = "generated.meta";
FilePath meta_file = test_dir_.path().Append(kMetaFileBasename);
FilePath payload_file = test_dir_.path().Append("payload-file");
+ FilePath osreleased_directory =
+ test_dir_.path().Append("etc").Append("os-release.d");
+ ASSERT_TRUE(base::CreateDirectory(osreleased_directory));
+ collector_.ForceOsReleaseDDirectory(test_dir_.path());
+
std::string contents;
const char kPayload[] = "foo";
ASSERT_TRUE(base::WriteFile(payload_file, kPayload, strlen(kPayload)));
+ const char kBdkVersion[] = "1";
+ ASSERT_TRUE(base::WriteFile(osreleased_directory.Append("bdk_version"),
+ kBdkVersion,
+ strlen(kBdkVersion)));
+ const char kProductId[] = "baz";
+ ASSERT_TRUE(base::WriteFile(osreleased_directory.Append("product_id"),
+ kProductId,
+ strlen(kProductId)));
+ const char kProductVersion[] = "1.2.3.4";
+ ASSERT_TRUE(base::WriteFile(osreleased_directory.Append("product_version"),
+ kProductVersion,
+ strlen(kProductVersion)));
collector_.AddCrashMetaData("foo", "bar");
collector_.WriteCrashMetaData(meta_file, "kernel", payload_file.value());
EXPECT_TRUE(base::ReadFileToString(meta_file, &contents));
@@ -193,6 +211,9 @@
"exec_name=kernel\n"
"payload=%s\n"
"payload_size=3\n"
+ "bdk_version=1\n"
+ "product_id=baz\n"
+ "product_version=1.2.3.4\n"
"done=1\n",
test_dir_.path().Append("payload-file").value().c_str());
EXPECT_EQ(kExpectedMeta, contents);
diff --git a/crash_reporter/kernel_collector_test.cc b/crash_reporter/kernel_collector_test.cc
index 015f624..60fd832 100644
--- a/crash_reporter/kernel_collector_test.cc
+++ b/crash_reporter/kernel_collector_test.cc
@@ -49,7 +49,9 @@
protected:
void WriteStringToFile(const FilePath &file_path,
const char *data) {
- ASSERT_EQ(strlen(data), base::WriteFile(file_path, data, strlen(data)));
+ unsigned int numBytesWritten =
+ base::WriteFile(file_path, data, strlen(data));
+ ASSERT_EQ(strlen(data), numBytesWritten);
}
void SetUpSuccessfulCollect();
@@ -284,7 +286,7 @@
size_t end_pos = filename.find_first_of("\n");
ASSERT_NE(std::string::npos, end_pos);
filename = filename.substr(0, end_pos);
- ASSERT_EQ(0, filename.find(test_crash_directory().value()));
+ ASSERT_EQ(0U, filename.find(test_crash_directory().value()));
ASSERT_TRUE(base::PathExists(FilePath(filename)));
std::string contents;
ASSERT_TRUE(base::ReadFileToString(FilePath(filename), &contents));
diff --git a/crash_reporter/unclean_shutdown_collector_test.cc b/crash_reporter/unclean_shutdown_collector_test.cc
index 56d2704..36372ae 100644
--- a/crash_reporter/unclean_shutdown_collector_test.cc
+++ b/crash_reporter/unclean_shutdown_collector_test.cc
@@ -73,7 +73,9 @@
protected:
void WriteStringToFile(const FilePath &file_path,
const char *data) {
- ASSERT_EQ(strlen(data), base::WriteFile(file_path, data, strlen(data)));
+ unsigned int numBytesWritten =
+ base::WriteFile(file_path, data, strlen(data));
+ ASSERT_EQ(strlen(data), numBytesWritten);
}
UncleanShutdownCollectorMock collector_;
diff --git a/crash_reporter/user_collector.cc b/crash_reporter/user_collector.cc
index 98d7448..48b64e9 100644
--- a/crash_reporter/user_collector.cc
+++ b/crash_reporter/user_collector.cc
@@ -37,7 +37,6 @@
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
-#include <brillo/osrelease_reader.h>
#include <brillo/process.h>
#include <brillo/syslog_logging.h>
#include <cutils/properties.h>
@@ -59,11 +58,6 @@
const char *UserCollector::kUserId = "Uid:\t";
const char *UserCollector::kGroupId = "Gid:\t";
-// Product information keys in the /etc/os-release.d folder.
-static const char kBdkVersionKey[] = "bdk_version";
-static const char kProductIDKey[] = "product_id";
-static const char kProductVersionKey[] = "product_version";
-
using base::FilePath;
using base::StringPrintf;
@@ -505,29 +499,6 @@
if (GetLogContents(FilePath(log_config_path_), exec, log_path))
AddCrashMetaData("log", log_path.value());
- brillo::OsReleaseReader reader;
- reader.Load();
- std::string value = "undefined";
- if (!reader.GetString(kBdkVersionKey, &value)) {
- LOG(ERROR) << "Could not read " << kBdkVersionKey
- << " from /etc/os-release.d/";
- }
- AddCrashMetaData(kBdkVersionKey, value);
-
- value = "undefined";
- if (!reader.GetString(kProductIDKey, &value)) {
- LOG(ERROR) << "Could not read " << kProductIDKey
- << " from /etc/os-release.d/";
- }
- AddCrashMetaData(kProductIDKey, value);
-
- value = "undefined";
- if (!reader.GetString(kProductVersionKey, &value)) {
- LOG(ERROR) << "Could not read " << kProductVersionKey
- << " from /etc/os-release.d/";
- }
- AddCrashMetaData(kProductVersionKey, value);
-
ErrorType error_type =
ConvertCoreToMinidump(pid, container_dir, core_path, minidump_path);
if (error_type != kErrorNone) {
diff --git a/crash_reporter/user_collector_test.cc b/crash_reporter/user_collector_test.cc
index d9c9a5b..16a5cd5 100644
--- a/crash_reporter/user_collector_test.cc
+++ b/crash_reporter/user_collector_test.cc
@@ -101,15 +101,15 @@
&pid, &signal, &uid, &gid, &exec_name));
EXPECT_EQ(123456, pid);
EXPECT_EQ(11, signal);
- EXPECT_EQ(1000, uid);
- EXPECT_EQ(2000, gid);
+ EXPECT_EQ(1000U, uid);
+ EXPECT_EQ(2000U, gid);
EXPECT_EQ("foobar", exec_name);
EXPECT_TRUE(collector_.ParseCrashAttributes("4321:6:barfoo",
&pid, &signal, &uid, &gid, &exec_name));
EXPECT_EQ(4321, pid);
EXPECT_EQ(6, signal);
- EXPECT_EQ(-1, uid);
- EXPECT_EQ(-1, gid);
+ EXPECT_EQ(-1U, uid);
+ EXPECT_EQ(-1U, gid);
EXPECT_EQ("barfoo", exec_name);
EXPECT_FALSE(collector_.ParseCrashAttributes("123456:11",
@@ -186,10 +186,10 @@
test_dir_.path().Append("test/this_link").value().c_str();
this_link.assign(long_link.c_str(), len);
ASSERT_EQ(len, this_link.size());
- unlink(kLink);
ASSERT_EQ(0, symlink(this_link.c_str(), kLink));
ASSERT_TRUE(collector_.GetSymlinkTarget(FilePath(kLink), &result));
ASSERT_EQ(this_link, result.value());
+ unlink(kLink);
}
}
@@ -333,8 +333,8 @@
gid_t gid = 100;
uid_t uid = 100;
EXPECT_TRUE(collector_.GetUserInfoFromName("root", &uid, &gid));
- EXPECT_EQ(0, uid);
- EXPECT_EQ(0, gid);
+ EXPECT_EQ(0U, uid);
+ EXPECT_EQ(0U, gid);
}
TEST_F(UserCollectorTest, CopyOffProcFilesBadPath) {
@@ -387,7 +387,9 @@
// maps file is not empty
const char data[] = "test data";
- ASSERT_EQ(sizeof(data), base::WriteFile(maps_file, data, sizeof(data)));
+ unsigned int numBytesWritten =
+ base::WriteFile(maps_file, data, sizeof(data));
+ ASSERT_EQ(sizeof(data), numBytesWritten);
ASSERT_TRUE(base::PathExists(maps_file));
EXPECT_TRUE(collector_.ValidateProcFiles(container_dir));
}
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 7f0e5bb..0a43622 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -42,7 +42,6 @@
#include <cutils/debugger.h>
#include <cutils/properties.h>
#include <cutils/sockets.h>
-#include <nativehelper/ScopedFd.h>
#include <linux/input.h>
@@ -692,7 +691,7 @@
static void handle_request(int fd) {
ALOGV("handle_request(%d)\n", fd);
- ScopedFd closer(fd);
+ android::base::unique_fd closer(fd);
debugger_request_t request;
memset(&request, 0, sizeof(request));
int status = read_request(fd, &request);
diff --git a/debuggerd/getevent.cpp b/debuggerd/getevent.cpp
index 751c4fb..e5acd17 100644
--- a/debuggerd/getevent.cpp
+++ b/debuggerd/getevent.cpp
@@ -26,6 +26,7 @@
#include <sys/poll.h>
#include <linux/input.h>
#include <errno.h>
+#include <memory>
#include <cutils/log.h>
static struct pollfd* ufds;
@@ -143,22 +144,20 @@
static int scan_dir(const char* dirname) {
char devname[PATH_MAX];
char* filename;
- DIR* dir;
struct dirent* de;
- dir = opendir(dirname);
+ std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(dirname), closedir);
if (dir == NULL)
return -1;
strcpy(devname, dirname);
filename = devname + strlen(devname);
*filename++ = '/';
- while ((de = readdir(dir))) {
+ while ((de = readdir(dir.get()))) {
if ((de->d_name[0] == '.' && de->d_name[1] == '\0') ||
(de->d_name[1] == '.' && de->d_name[2] == '\0'))
continue;
strcpy(filename, de->d_name);
open_device(devname);
}
- closedir(dir);
return 0;
}
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 636092e..3f820b6 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -357,8 +357,8 @@
" formatting.\n"
" -s <specific device> Specify a device. For USB, provide either\n"
" a serial number or path to device port.\n"
- " For ethernet, provide an address in the"
- " form <protocol>:<hostname>[:port] where"
+ " For ethernet, provide an address in the\n"
+ " form <protocol>:<hostname>[:port] where\n"
" <protocol> is either tcp or udp.\n"
" -p <product> Specify product name.\n"
" -c <cmdline> Override kernel commandline.\n"
diff --git a/fastboot/protocol.cpp b/fastboot/protocol.cpp
index 4850b4a..1785b76 100644
--- a/fastboot/protocol.cpp
+++ b/fastboot/protocol.cpp
@@ -54,14 +54,14 @@
while (true) {
int r = transport->Read(status, 64);
if (r < 0) {
- sprintf(ERROR, "status read failed (%s)", strerror(errno));
+ snprintf(ERROR, sizeof(ERROR), "status read failed (%s)", strerror(errno));
transport->Close();
return -1;
}
status[r] = 0;
if (r < 4) {
- sprintf(ERROR, "status malformed (%d bytes)", r);
+ snprintf(ERROR, sizeof(ERROR), "status malformed (%d bytes)", r);
transport->Close();
return -1;
}
@@ -80,7 +80,7 @@
if (!memcmp(status, "FAIL", 4)) {
if (r > 4) {
- sprintf(ERROR, "remote: %s", status + 4);
+ snprintf(ERROR, sizeof(ERROR), "remote: %s", status + 4);
} else {
strcpy(ERROR, "remote failure");
}
@@ -108,7 +108,7 @@
static int _command_start(Transport* transport, const char* cmd, uint32_t size, char* response) {
size_t cmdsize = strlen(cmd);
if (cmdsize > 64) {
- sprintf(ERROR, "command too large");
+ snprintf(ERROR, sizeof(ERROR), "command too large");
return -1;
}
@@ -117,7 +117,7 @@
}
if (transport->Write(cmd, cmdsize) != static_cast<int>(cmdsize)) {
- sprintf(ERROR, "command write failed (%s)", strerror(errno));
+ snprintf(ERROR, sizeof(ERROR), "command write failed (%s)", strerror(errno));
transport->Close();
return -1;
}
@@ -128,12 +128,12 @@
static int _command_data(Transport* transport, const void* data, uint32_t size) {
int r = transport->Write(data, size);
if (r < 0) {
- sprintf(ERROR, "data transfer failure (%s)", strerror(errno));
+ snprintf(ERROR, sizeof(ERROR), "data transfer failure (%s)", strerror(errno));
transport->Close();
return -1;
}
if (r != ((int) size)) {
- sprintf(ERROR, "data transfer failure (short transfer)");
+ snprintf(ERROR, sizeof(ERROR), "data transfer failure (short transfer)");
transport->Close();
return -1;
}
@@ -182,7 +182,7 @@
int fb_download_data(Transport* transport, const void* data, uint32_t size) {
char cmd[64];
- sprintf(cmd, "download:%08x", size);
+ snprintf(cmd, sizeof(cmd), "download:%08x", size);
return _command_send(transport, cmd, data, size, 0) < 0 ? -1 : 0;
}
@@ -216,7 +216,7 @@
if (len > TRANSPORT_BUF_SIZE) {
if (transport_buf_len > 0) {
- sprintf(ERROR, "internal error: transport_buf not empty\n");
+ snprintf(ERROR, sizeof(ERROR), "internal error: transport_buf not empty\n");
return -1;
}
to_write = round_down(len, TRANSPORT_BUF_SIZE);
@@ -230,7 +230,7 @@
if (len > 0) {
if (len > TRANSPORT_BUF_SIZE) {
- sprintf(ERROR, "internal error: too much left for transport_buf\n");
+ snprintf(ERROR, sizeof(ERROR), "internal error: too much left for transport_buf\n");
return -1;
}
memcpy(transport_buf, ptr, len);
@@ -257,7 +257,7 @@
}
char cmd[64];
- sprintf(cmd, "download:%08x", size);
+ snprintf(cmd, sizeof(cmd), "download:%08x", size);
int r = _command_start(transport, cmd, size, 0);
if (r < 0) {
return -1;
diff --git a/fastboot/usb_linux.cpp b/fastboot/usb_linux.cpp
index 02ffcd9..d4824fb 100644
--- a/fastboot/usb_linux.cpp
+++ b/fastboot/usb_linux.cpp
@@ -145,7 +145,7 @@
int in, out;
unsigned i;
unsigned e;
-
+
if (check(ptr, len, USB_DT_DEVICE, USB_DT_DEVICE_SIZE))
return -1;
dev = (struct usb_device_descriptor *)ptr;
@@ -333,15 +333,14 @@
char desc[1024];
int n, in, out, ifc;
- DIR *busdir;
struct dirent *de;
int fd;
int writable;
- busdir = opendir(base);
+ std::unique_ptr<DIR, decltype(&closedir)> busdir(opendir(base), closedir);
if (busdir == 0) return 0;
- while ((de = readdir(busdir)) && (usb == nullptr)) {
+ while ((de = readdir(busdir.get())) && (usb == nullptr)) {
if (badname(de->d_name)) continue;
if (!convert_to_devfs_name(de->d_name, devname, sizeof(devname))) {
@@ -377,7 +376,6 @@
}
}
}
- closedir(busdir);
return usb;
}
diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk
index 28fff3f..d0d5630 100644
--- a/fs_mgr/Android.mk
+++ b/fs_mgr/Android.mk
@@ -7,7 +7,7 @@
libfec \
libfec_rs \
libbase \
- libmincrypt \
+ libcrypto_utils_static \
libcrypto_static \
libext4_utils_static \
libsquashfs_utils
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 70acd38..9fc5999 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -14,35 +14,32 @@
* limitations under the License.
*/
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <ctype.h>
#include <sys/mount.h>
#include <sys/stat.h>
-#include <errno.h>
+#include <sys/swap.h>
#include <sys/types.h>
#include <sys/wait.h>
-#include <libgen.h>
#include <time.h>
-#include <sys/swap.h>
-#include <dirent.h>
-#include <ext4.h>
-#include <ext4_sb.h>
-#include <ext4_crypt_init_extensions.h>
+#include <unistd.h>
-#include <linux/loop.h>
-#include <private/android_filesystem_config.h>
+#include <ext4.h>
+#include <ext4_crypt_init_extensions.h>
+#include <ext4_sb.h>
+
#include <cutils/android_reboot.h>
#include <cutils/partition_utils.h>
#include <cutils/properties.h>
+#include <linux/loop.h>
#include <logwrap/logwrap.h>
-
-#include "mincrypt/rsa.h"
-#include "mincrypt/sha.h"
-#include "mincrypt/sha256.h"
+#include <private/android_filesystem_config.h>
#include "ext4_utils.h"
#include "wipe.h"
@@ -588,7 +585,7 @@
fstab->recs[top_idx].fs_type);
if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
- int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY, 0644);
+ int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY);
if (fd >= 0) {
INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc);
wipe_block_device(fd, get_file_size(fd));
diff --git a/fs_mgr/fs_mgr_format.c b/fs_mgr/fs_mgr_format.c
index f8df081..0b52e00 100644
--- a/fs_mgr/fs_mgr_format.c
+++ b/fs_mgr/fs_mgr_format.c
@@ -33,15 +33,15 @@
static int format_ext4(char *fs_blkdev, char *fs_mnt_point)
{
- unsigned int nr_sec;
+ uint64_t dev_sz;
int fd, rc = 0;
- if ((fd = open(fs_blkdev, O_WRONLY, 0644)) < 0) {
+ if ((fd = open(fs_blkdev, O_WRONLY)) < 0) {
ERROR("Cannot open block device. %s\n", strerror(errno));
return -1;
}
- if ((ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) {
+ if ((ioctl(fd, BLKGETSIZE64, &dev_sz)) == -1) {
ERROR("Cannot get block device size. %s\n", strerror(errno));
close(fd);
return -1;
@@ -49,7 +49,7 @@
/* Format the partition using the calculated length */
reset_ext4fs_info();
- info.len = ((off64_t)nr_sec * 512);
+ info.len = (off64_t)dev_sz;
/* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */
rc = make_ext4fs_internal(fd, NULL, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL);
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index b5141c9..129a5bb 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -14,29 +14,29 @@
* limitations under the License.
*/
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
#include <inttypes.h>
+#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <ctype.h>
#include <sys/mount.h>
#include <sys/stat.h>
-#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
-#include <libgen.h>
#include <time.h>
+#include <unistd.h>
#include <android-base/file.h>
-#include <private/android_filesystem_config.h>
+#include <crypto_utils/android_pubkey.h>
#include <cutils/properties.h>
#include <logwrap/logwrap.h>
-
-#include "mincrypt/rsa.h"
-#include "mincrypt/sha.h"
-#include "mincrypt/sha256.h"
+#include <openssl/obj_mac.h>
+#include <openssl/rsa.h>
+#include <openssl/sha.h>
+#include <private/android_filesystem_config.h>
#include "fec/io.h"
@@ -83,48 +83,45 @@
extern struct fs_info info;
-static RSAPublicKey *load_key(const char *path)
+static RSA *load_key(const char *path)
{
- RSAPublicKey* key = static_cast<RSAPublicKey*>(malloc(sizeof(RSAPublicKey)));
- if (!key) {
- ERROR("Can't malloc key\n");
- return NULL;
- }
+ uint8_t key_data[ANDROID_PUBKEY_ENCODED_SIZE];
FILE* f = fopen(path, "r");
if (!f) {
ERROR("Can't open '%s'\n", path);
- free(key);
+ free(key_data);
return NULL;
}
- if (!fread(key, sizeof(*key), 1, f)) {
+ if (!fread(key_data, sizeof(key_data), 1, f)) {
ERROR("Could not read key!\n");
fclose(f);
- free(key);
- return NULL;
- }
-
- if (key->len != RSANUMWORDS) {
- ERROR("Invalid key length %d\n", key->len);
- fclose(f);
- free(key);
+ free(key_data);
return NULL;
}
fclose(f);
+
+ RSA* key = NULL;
+ if (!android_pubkey_decode(key_data, sizeof(key_data), &key)) {
+ ERROR("Could not parse key!\n");
+ free(key_data);
+ return NULL;
+ }
+
return key;
}
-static int verify_table(const uint8_t *signature, const char *table,
- uint32_t table_length)
+static int verify_table(const uint8_t *signature, size_t signature_size,
+ const char *table, uint32_t table_length)
{
- RSAPublicKey *key;
- uint8_t hash_buf[SHA256_DIGEST_SIZE];
+ RSA *key;
+ uint8_t hash_buf[SHA256_DIGEST_LENGTH];
int retval = -1;
// Hash the table
- SHA256_hash((uint8_t*)table, table_length, hash_buf);
+ SHA256((uint8_t*)table, table_length, hash_buf);
// Now get the public key from the keyfile
key = load_key(VERITY_TABLE_RSA_KEY);
@@ -134,11 +131,8 @@
}
// verify the result
- if (!RSA_verify(key,
- signature,
- RSANUMBYTES,
- (uint8_t*) hash_buf,
- SHA256_DIGEST_SIZE)) {
+ if (!RSA_verify(NID_sha256, hash_buf, sizeof(hash_buf), signature,
+ signature_size, key)) {
ERROR("Couldn't verify table\n");
goto out;
}
@@ -146,7 +140,7 @@
retval = 0;
out:
- free(key);
+ RSA_free(key);
return retval;
}
@@ -610,8 +604,8 @@
off64_t offset = 0;
struct fec_handle *f = NULL;
struct fec_verity_metadata verity;
- uint8_t curr[SHA256_DIGEST_SIZE];
- uint8_t prev[SHA256_DIGEST_SIZE];
+ uint8_t curr[SHA256_DIGEST_LENGTH];
+ uint8_t prev[SHA256_DIGEST_LENGTH];
*match = 1;
@@ -629,7 +623,7 @@
goto out;
}
- SHA256_hash(verity.signature, RSANUMBYTES, curr);
+ SHA256(verity.signature, sizeof(verity.signature), curr);
if (snprintf(tag, sizeof(tag), VERITY_LASTSIG_TAG "_%s",
basename(fstab->mount_point)) >= (int)sizeof(tag)) {
@@ -637,7 +631,7 @@
goto out;
}
- if (metadata_find(fstab->verity_loc, tag, SHA256_DIGEST_SIZE,
+ if (metadata_find(fstab->verity_loc, tag, SHA256_DIGEST_LENGTH,
&offset) < 0) {
goto out;
}
@@ -656,7 +650,7 @@
goto out;
}
- *match = !memcmp(curr, prev, SHA256_DIGEST_SIZE);
+ *match = !memcmp(curr, prev, SHA256_DIGEST_LENGTH);
if (!*match) {
/* update current signature hash */
@@ -919,7 +913,7 @@
}
// verify the signature on the table
- if (verify_table(verity.signature, verity.table,
+ if (verify_table(verity.signature, sizeof(verity.signature), verity.table,
verity.table_length) < 0) {
if (params.mode == VERITY_MODE_LOGGING) {
// the user has been warned, allow mounting without dm-verity
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index b4fdab0..7254cf2 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -76,7 +76,7 @@
void store_sid(uint32_t uid, uint64_t sid) {
char filename[21];
- sprintf(filename, "%u", uid);
+ snprintf(filename, sizeof(filename), "%u", uid);
int fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
if (fd < 0) {
ALOGE("could not open file: %s: %s", filename, strerror(errno));
@@ -102,7 +102,7 @@
void maybe_store_sid(uint32_t uid, uint64_t sid) {
char filename[21];
- sprintf(filename, "%u", uid);
+ snprintf(filename, sizeof(filename), "%u", uid);
if (access(filename, F_OK) == -1) {
store_sid(uid, sid);
}
@@ -111,7 +111,7 @@
uint64_t read_sid(uint32_t uid) {
char filename[21];
uint64_t sid;
- sprintf(filename, "%u", uid);
+ snprintf(filename, sizeof(filename), "%u", uid);
int fd = open(filename, O_RDONLY);
if (fd < 0) return 0;
read(fd, &sid, sizeof(sid));
@@ -121,7 +121,7 @@
void clear_sid(uint32_t uid) {
char filename[21];
- sprintf(filename, "%u", uid);
+ snprintf(filename, sizeof(filename), "%u", uid);
if (remove(filename) < 0) {
ALOGE("%s: could not remove file [%s], attempting 0 write", __func__, strerror(errno));
store_sid(uid, 0);
diff --git a/healthd/Android.mk b/healthd/Android.mk
index a4469fc..127f39e 100644
--- a/healthd/Android.mk
+++ b/healthd/Android.mk
@@ -8,6 +8,8 @@
LOCAL_CFLAGS := -Werror
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_STATIC_LIBRARIES := libbinder
+LOCAL_EXPORT_STATIC_LIBRARY_HEADERS := libbinder
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
@@ -15,17 +17,27 @@
LOCAL_MODULE := libbatterymonitor
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_STATIC_LIBRARIES := libutils
+LOCAL_STATIC_LIBRARIES := libutils libbinder
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
+ifeq ($(strip $(BOARD_CHARGER_NO_UI)),true)
+LOCAL_CHARGER_NO_UI := true
+endif
+ifdef BRILLO
+LOCAL_CHARGER_NO_UI := true
+endif
+
LOCAL_SRC_FILES := \
healthd.cpp \
healthd_mode_android.cpp \
- healthd_mode_charger.cpp \
BatteryPropertiesRegistrar.cpp
+ifneq ($(strip $(LOCAL_CHARGER_NO_UI)),true)
+LOCAL_SRC_FILES += healthd_mode_charger.cpp
+endif
+
LOCAL_MODULE := healthd
LOCAL_MODULE_TAGS := optional
LOCAL_FORCE_STATIC_EXECUTABLE := true
@@ -42,9 +54,19 @@
LOCAL_CFLAGS += -DCHARGER_ENABLE_SUSPEND
endif
-LOCAL_C_INCLUDES := bootable/recovery
+ifeq ($(strip $(LOCAL_CHARGER_NO_UI)),true)
+LOCAL_CFLAGS += -DCHARGER_NO_UI
+endif
-LOCAL_STATIC_LIBRARIES := libbatterymonitor libbatteryservice libbinder libminui libpng libz libutils libcutils liblog libm libc
+LOCAL_C_INCLUDES := bootable/recovery $(LOCAL_PATH)/include
+
+LOCAL_STATIC_LIBRARIES := libbatterymonitor libbatteryservice libbinder
+
+ifneq ($(strip $(LOCAL_CHARGER_NO_UI)),true)
+LOCAL_STATIC_LIBRARIES += libminui libpng libz
+endif
+
+LOCAL_STATIC_LIBRARIES += libutils libcutils liblog libm libc
ifeq ($(strip $(BOARD_CHARGER_ENABLE_SUSPEND)),true)
LOCAL_STATIC_LIBRARIES += libsuspend
@@ -59,6 +81,7 @@
include $(BUILD_EXECUTABLE)
+ifneq ($(strip $(LOCAL_CHARGER_NO_UI)),true)
define _add-charger-image
include $$(CLEAR_VARS)
LOCAL_MODULE := system_core_charger_$(notdir $(1))
@@ -84,3 +107,4 @@
_add-charger-image :=
_img_modules :=
+endif # LOCAL_CHARGER_NO_UI
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index a8646c5..d287d10 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
+#include <memory>
#include <batteryservice/BatteryService.h>
#include <cutils/klog.h>
@@ -342,11 +343,10 @@
" cc=%d", props.batteryCycleCount);
}
} else {
- snprintf(dmesgline, sizeof(dmesgline),
+ len = snprintf(dmesgline, sizeof(dmesgline),
"battery none");
}
- len = strlen(dmesgline);
snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s",
props.chargerAcOnline ? "a" : "",
props.chargerUsbOnline ? "u" : "",
@@ -488,13 +488,13 @@
char pval[PROPERTY_VALUE_MAX];
mHealthdConfig = hc;
- DIR* dir = opendir(POWER_SUPPLY_SYSFS_PATH);
+ std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(POWER_SUPPLY_SYSFS_PATH), closedir);
if (dir == NULL) {
KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
} else {
struct dirent* entry;
- while ((entry = readdir(dir))) {
+ while ((entry = readdir(dir.get()))) {
const char* name = entry->d_name;
if (!strcmp(name, ".") || !strcmp(name, ".."))
@@ -632,22 +632,17 @@
break;
}
}
- closedir(dir);
}
- // This indicates that there is no charger driver registered.
// Typically the case for devices which do not have a battery and
// and are always plugged into AC mains.
- if (!mChargerNames.size()) {
- KLOG_ERROR(LOG_TAG, "No charger supplies found\n");
- mBatteryFixedCapacity = ALWAYS_PLUGGED_CAPACITY;
- mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
- mAlwaysPluggedDevice = true;
- }
if (!mBatteryDevicePresent) {
KLOG_WARNING(LOG_TAG, "No battery devices found\n");
hc->periodic_chores_interval_fast = -1;
hc->periodic_chores_interval_slow = -1;
+ mBatteryFixedCapacity = ALWAYS_PLUGGED_CAPACITY;
+ mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
+ mAlwaysPluggedDevice = true;
} else {
if (mHealthdConfig->batteryStatusPath.isEmpty())
KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp
index d9ac356..20a6bf6 100644
--- a/healthd/healthd.cpp
+++ b/healthd/healthd.cpp
@@ -109,10 +109,17 @@
};
static struct healthd_mode_ops charger_ops = {
+#ifdef CHARGER_NO_UI
+ .init = healthd_mode_nop_init,
+ .preparetowait = healthd_mode_nop_preparetowait,
+ .heartbeat = healthd_mode_nop_heartbeat,
+ .battery_update = healthd_mode_nop_battery_update,
+#else
.init = healthd_mode_charger_init,
.preparetowait = healthd_mode_charger_preparetowait,
.heartbeat = healthd_mode_charger_heartbeat,
.battery_update = healthd_mode_charger_battery_update,
+#endif
};
static struct healthd_mode_ops recovery_ops = {
diff --git a/include/binderwrapper/binder_wrapper.h b/include/binderwrapper/binder_wrapper.h
index ccda825..a104bff 100644
--- a/include/binderwrapper/binder_wrapper.h
+++ b/include/binderwrapper/binder_wrapper.h
@@ -70,7 +70,7 @@
// is currently registered for |binder|, it will be replaced.
virtual bool RegisterForDeathNotifications(
const sp<IBinder>& binder,
- const base::Closure& callback) = 0;
+ const ::base::Closure& callback) = 0;
// Unregisters the callback, if any, for |binder|.
virtual bool UnregisterForDeathNotifications(const sp<IBinder>& binder) = 0;
diff --git a/include/binderwrapper/stub_binder_wrapper.h b/include/binderwrapper/stub_binder_wrapper.h
index 01c9648..9d4578e 100644
--- a/include/binderwrapper/stub_binder_wrapper.h
+++ b/include/binderwrapper/stub_binder_wrapper.h
@@ -98,7 +98,7 @@
const sp<IBinder>& binder) override;
sp<BBinder> CreateLocalBinder() override;
bool RegisterForDeathNotifications(const sp<IBinder>& binder,
- const base::Closure& callback) override;
+ const ::base::Closure& callback) override;
bool UnregisterForDeathNotifications(const sp<IBinder>& binder) override;
uid_t GetCallingUid() override;
pid_t GetCallingPid() override;
@@ -119,7 +119,7 @@
// Map from binder handle to the callback that should be invoked on binder
// death.
- std::map<sp<IBinder>, base::Closure> death_callbacks_;
+ std::map<sp<IBinder>, ::base::Closure> death_callbacks_;
// Values to return from GetCallingUid() and GetCallingPid();
uid_t calling_uid_;
diff --git a/include/mincrypt/dsa_sig.h b/include/mincrypt/dsa_sig.h
deleted file mode 100644
index b0d91cd..0000000
--- a/include/mincrypt/dsa_sig.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Google Inc. nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_DSA_SIG_H_
-#define SYSTEM_CORE_INCLUDE_MINCRYPT_DSA_SIG_H_
-
-#include "mincrypt/p256.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Returns 0 if input sig is not a valid ASN.1 sequence
-int dsa_sig_unpack(unsigned char* sig, int sig_len, p256_int* r_int, p256_int* s_int);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* SYSTEM_CORE_INCLUDE_MINCRYPT_DSA_SIG_H_ */
diff --git a/include/mincrypt/hash-internal.h b/include/mincrypt/hash-internal.h
deleted file mode 100644
index c813b44..0000000
--- a/include/mincrypt/hash-internal.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2007 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Google Inc. nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_HASH_INTERNAL_H_
-#define SYSTEM_CORE_INCLUDE_MINCRYPT_HASH_INTERNAL_H_
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-struct HASH_CTX; // forward decl
-
-typedef struct HASH_VTAB {
- void (* const init)(struct HASH_CTX*);
- void (* const update)(struct HASH_CTX*, const void*, int);
- const uint8_t* (* const final)(struct HASH_CTX*);
- const uint8_t* (* const hash)(const void*, int, uint8_t*);
- int size;
-} HASH_VTAB;
-
-typedef struct HASH_CTX {
- const HASH_VTAB * f;
- uint64_t count;
- uint8_t buf[64];
- uint32_t state[8]; // upto SHA2
-} HASH_CTX;
-
-#define HASH_init(ctx) (ctx)->f->init(ctx)
-#define HASH_update(ctx, data, len) (ctx)->f->update(ctx, data, len)
-#define HASH_final(ctx) (ctx)->f->final(ctx)
-#define HASH_hash(data, len, digest) (ctx)->f->hash(data, len, digest)
-#define HASH_size(ctx) (ctx)->f->size
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif // SYSTEM_CORE_INCLUDE_MINCRYPT_HASH_INTERNAL_H_
diff --git a/include/mincrypt/p256.h b/include/mincrypt/p256.h
deleted file mode 100644
index 465a1b9..0000000
--- a/include/mincrypt/p256.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Google Inc. nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_LITE_P256_H_
-#define SYSTEM_CORE_INCLUDE_MINCRYPT_LITE_P256_H_
-
-// Collection of routines manipulating 256 bit unsigned integers.
-// Just enough to implement ecdsa-p256 and related algorithms.
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define P256_BITSPERDIGIT 32
-#define P256_NDIGITS 8
-#define P256_NBYTES 32
-
-typedef int p256_err;
-typedef uint32_t p256_digit;
-typedef int32_t p256_sdigit;
-typedef uint64_t p256_ddigit;
-typedef int64_t p256_sddigit;
-
-// Defining p256_int as struct to leverage struct assigment.
-typedef struct {
- p256_digit a[P256_NDIGITS];
-} p256_int;
-
-extern const p256_int SECP256r1_n; // Curve order
-extern const p256_int SECP256r1_p; // Curve prime
-extern const p256_int SECP256r1_b; // Curve param
-
-// Initialize a p256_int to zero.
-void p256_init(p256_int* a);
-
-// Clear a p256_int to zero.
-void p256_clear(p256_int* a);
-
-// Return bit. Index 0 is least significant.
-int p256_get_bit(const p256_int* a, int index);
-
-// b := a % MOD
-void p256_mod(
- const p256_int* MOD,
- const p256_int* a,
- p256_int* b);
-
-// c := a * (top_b | b) % MOD
-void p256_modmul(
- const p256_int* MOD,
- const p256_int* a,
- const p256_digit top_b,
- const p256_int* b,
- p256_int* c);
-
-// b := 1 / a % MOD
-// MOD best be SECP256r1_n
-void p256_modinv(
- const p256_int* MOD,
- const p256_int* a,
- p256_int* b);
-
-// b := 1 / a % MOD
-// MOD best be SECP256r1_n
-// Faster than p256_modinv()
-void p256_modinv_vartime(
- const p256_int* MOD,
- const p256_int* a,
- p256_int* b);
-
-// b := a << (n % P256_BITSPERDIGIT)
-// Returns the bits shifted out of most significant digit.
-p256_digit p256_shl(const p256_int* a, int n, p256_int* b);
-
-// b := a >> (n % P256_BITSPERDIGIT)
-void p256_shr(const p256_int* a, int n, p256_int* b);
-
-int p256_is_zero(const p256_int* a);
-int p256_is_odd(const p256_int* a);
-int p256_is_even(const p256_int* a);
-
-// Returns -1, 0 or 1.
-int p256_cmp(const p256_int* a, const p256_int *b);
-
-// c: = a - b
-// Returns -1 on borrow.
-int p256_sub(const p256_int* a, const p256_int* b, p256_int* c);
-
-// c := a + b
-// Returns 1 on carry.
-int p256_add(const p256_int* a, const p256_int* b, p256_int* c);
-
-// c := a + (single digit)b
-// Returns carry 1 on carry.
-int p256_add_d(const p256_int* a, p256_digit b, p256_int* c);
-
-// ec routines.
-
-// {out_x,out_y} := nG
-void p256_base_point_mul(const p256_int *n,
- p256_int *out_x,
- p256_int *out_y);
-
-// {out_x,out_y} := n{in_x,in_y}
-void p256_point_mul(const p256_int *n,
- const p256_int *in_x,
- const p256_int *in_y,
- p256_int *out_x,
- p256_int *out_y);
-
-// {out_x,out_y} := n1G + n2{in_x,in_y}
-void p256_points_mul_vartime(
- const p256_int *n1, const p256_int *n2,
- const p256_int *in_x, const p256_int *in_y,
- p256_int *out_x, p256_int *out_y);
-
-// Return whether point {x,y} is on curve.
-int p256_is_valid_point(const p256_int* x, const p256_int* y);
-
-// Outputs big-endian binary form. No leading zero skips.
-void p256_to_bin(const p256_int* src, uint8_t dst[P256_NBYTES]);
-
-// Reads from big-endian binary form,
-// thus pre-pad with leading zeros if short.
-void p256_from_bin(const uint8_t src[P256_NBYTES], p256_int* dst);
-
-#define P256_DIGITS(x) ((x)->a)
-#define P256_DIGIT(x,y) ((x)->a[y])
-
-#define P256_ZERO {{0}}
-#define P256_ONE {{1}}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // SYSTEM_CORE_INCLUDE_MINCRYPT_LITE_P256_H_
diff --git a/include/mincrypt/p256_ecdsa.h b/include/mincrypt/p256_ecdsa.h
deleted file mode 100644
index da339fa..0000000
--- a/include/mincrypt/p256_ecdsa.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Google Inc. nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_P256_ECDSA_H_
-#define SYSTEM_CORE_INCLUDE_MINCRYPT_P256_ECDSA_H_
-
-// Using current directory as relative include path here since
-// this code typically gets lifted into a variety of build systems
-// and directory structures.
-#include "p256.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Returns 0 if {r,s} is not a signature on message for
-// public key {key_x,key_y}.
-//
-// Note: message is a p256_int.
-// Convert from a binary string using p256_from_bin().
-int p256_ecdsa_verify(const p256_int* key_x,
- const p256_int* key_y,
- const p256_int* message,
- const p256_int* r, const p256_int* s);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // SYSTEM_CORE_INCLUDE_MINCRYPT_P256_ECDSA_H_
diff --git a/include/mincrypt/rsa.h b/include/mincrypt/rsa.h
deleted file mode 100644
index 3d0556b..0000000
--- a/include/mincrypt/rsa.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* rsa.h
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of Google Inc. nor the names of its contributors may
-** be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
-** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_RSA_H_
-#define SYSTEM_CORE_INCLUDE_MINCRYPT_RSA_H_
-
-#include <inttypes.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define RSANUMBYTES 256 /* 2048 bit key length */
-#define RSANUMWORDS (RSANUMBYTES / sizeof(uint32_t))
-
-typedef struct RSAPublicKey {
- int len; /* Length of n[] in number of uint32_t */
- uint32_t n0inv; /* -1 / n[0] mod 2^32 */
- uint32_t n[RSANUMWORDS]; /* modulus as little endian array */
- uint32_t rr[RSANUMWORDS]; /* R^2 as little endian array */
- int exponent; /* 3 or 65537 */
-} RSAPublicKey;
-
-int RSA_verify(const RSAPublicKey *key,
- const uint8_t* signature,
- const int len,
- const uint8_t* hash,
- const int hash_len);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // SYSTEM_CORE_INCLUDE_MINCRYPT_RSA_H_
diff --git a/include/mincrypt/sha.h b/include/mincrypt/sha.h
deleted file mode 100644
index ef60aab..0000000
--- a/include/mincrypt/sha.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2005 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Google Inc. nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_SHA1_H_
-#define SYSTEM_CORE_INCLUDE_MINCRYPT_SHA1_H_
-
-#include <stdint.h>
-#include "hash-internal.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-typedef HASH_CTX SHA_CTX;
-
-void SHA_init(SHA_CTX* ctx);
-void SHA_update(SHA_CTX* ctx, const void* data, int len);
-const uint8_t* SHA_final(SHA_CTX* ctx);
-
-// Convenience method. Returns digest address.
-// NOTE: *digest needs to hold SHA_DIGEST_SIZE bytes.
-const uint8_t* SHA_hash(const void* data, int len, uint8_t* digest);
-
-#define SHA_DIGEST_SIZE 20
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif // SYSTEM_CORE_INCLUDE_MINCRYPT_SHA1_H_
diff --git a/include/mincrypt/sha256.h b/include/mincrypt/sha256.h
deleted file mode 100644
index 3a87c31..0000000
--- a/include/mincrypt/sha256.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2011 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Google Inc. nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_SHA256_H_
-#define SYSTEM_CORE_INCLUDE_MINCRYPT_SHA256_H_
-
-#include <stdint.h>
-#include "hash-internal.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-typedef HASH_CTX SHA256_CTX;
-
-void SHA256_init(SHA256_CTX* ctx);
-void SHA256_update(SHA256_CTX* ctx, const void* data, int len);
-const uint8_t* SHA256_final(SHA256_CTX* ctx);
-
-// Convenience method. Returns digest address.
-const uint8_t* SHA256_hash(const void* data, int len, uint8_t* digest);
-
-#define SHA256_DIGEST_SIZE 32
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif // SYSTEM_CORE_INCLUDE_MINCRYPT_SHA256_H_
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index c220a0c..e540de2 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -89,6 +89,10 @@
#define AID_DEBUGGERD 1045 /* debuggerd unprivileged user */
#define AID_MEDIA_CODEC 1046 /* mediacodec process */
#define AID_CAMERASERVER 1047 /* cameraserver process */
+#define AID_FIREWALL 1048 /* firewalld process */
+#define AID_TRUNKS 1049 /* trunksd process (TPM daemon) */
+#define AID_NVRAM 1050 /* Access-controlled NVRAM */
+/* Changes to this file must be made in AOSP, *not* in internal branches. */
#define AID_SHELL 2000 /* adb and debug shell user */
#define AID_CACHE 2001 /* cache access */
@@ -196,6 +200,9 @@
{ "debuggerd", AID_DEBUGGERD, },
{ "mediacodec", AID_MEDIA_CODEC, },
{ "cameraserver", AID_CAMERASERVER, },
+ { "firewall", AID_FIREWALL, },
+ { "trunks", AID_TRUNKS, },
+ { "nvram", AID_NVRAM, },
{ "shell", AID_SHELL, },
{ "cache", AID_CACHE, },
diff --git a/include/utils/Condition.h b/include/utils/Condition.h
index 5a72519..a420185 100644
--- a/include/utils/Condition.h
+++ b/include/utils/Condition.h
@@ -106,30 +106,40 @@
return -pthread_cond_wait(&mCond, &mutex.mMutex);
}
inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
-#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
- struct timespec ts;
- ts.tv_sec = reltime/1000000000;
- ts.tv_nsec = reltime%1000000000;
- return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);
-#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
struct timespec ts;
#if defined(__linux__)
clock_gettime(CLOCK_REALTIME, &ts);
#else // __APPLE__
- // we don't support the clocks here.
+ // Apple doesn't support POSIX clocks.
struct timeval t;
gettimeofday(&t, NULL);
ts.tv_sec = t.tv_sec;
- ts.tv_nsec= t.tv_usec*1000;
+ ts.tv_nsec = t.tv_usec*1000;
#endif
- ts.tv_sec += reltime/1000000000;
- ts.tv_nsec+= reltime%1000000000;
- if (ts.tv_nsec >= 1000000000) {
+
+ // On 32-bit devices, tv_sec is 32-bit, but `reltime` is 64-bit.
+ int64_t reltime_sec = reltime/1000000000;
+
+ ts.tv_nsec += reltime%1000000000;
+ if (reltime_sec < INT64_MAX && ts.tv_nsec >= 1000000000) {
ts.tv_nsec -= 1000000000;
- ts.tv_sec += 1;
+ ++reltime_sec;
}
+
+ int64_t time_sec = ts.tv_sec;
+ if (time_sec > INT64_MAX - reltime_sec) {
+ time_sec = INT64_MAX;
+ } else {
+ time_sec += reltime_sec;
+ }
+
+#if defined(__LP64__)
+ ts.tv_sec = time_sec;
+#else
+ ts.tv_sec = (time_sec > INT32_MAX) ? INT32_MAX : time_sec;
+#endif
+
return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);
-#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
}
inline void Condition::signal() {
/*
diff --git a/include/utils/String16.h b/include/utils/String16.h
index 9a67c7a..4a5874a 100644
--- a/include/utils/String16.h
+++ b/include/utils/String16.h
@@ -17,8 +17,10 @@
#ifndef ANDROID_STRING16_H
#define ANDROID_STRING16_H
+#include <string> // for std::string
+
#include <utils/Errors.h>
-#include <utils/Unicode.h>
+#include <utils/String8.h>
#include <utils/TypeHelpers.h>
// ---------------------------------------------------------------------------
@@ -62,9 +64,10 @@
explicit String16(const char* o, size_t len);
~String16();
-
+
inline const char16_t* string() const;
-
+
+ static inline std::string std_string(const String16& str);
size_t size() const;
void setTo(const String16& other);
status_t setTo(const char16_t* other);
@@ -72,12 +75,12 @@
status_t setTo(const String16& other,
size_t len,
size_t begin=0);
-
+
status_t append(const String16& other);
status_t append(const char16_t* other, size_t len);
-
+
inline String16& operator=(const String16& other);
-
+
inline String16& operator+=(const String16& other);
inline String16 operator+(const String16& other) const;
@@ -90,7 +93,7 @@
bool startsWith(const String16& prefix) const;
bool startsWith(const char16_t* prefix) const;
-
+
status_t makeLower();
status_t replaceAll(char16_t replaceThis,
@@ -106,16 +109,16 @@
inline bool operator!=(const String16& other) const;
inline bool operator>=(const String16& other) const;
inline bool operator>(const String16& other) const;
-
+
inline bool operator<(const char16_t* other) const;
inline bool operator<=(const char16_t* other) const;
inline bool operator==(const char16_t* other) const;
inline bool operator!=(const char16_t* other) const;
inline bool operator>=(const char16_t* other) const;
inline bool operator>(const char16_t* other) const;
-
+
inline operator const char16_t*() const;
-
+
private:
const char16_t* mString;
};
@@ -142,6 +145,11 @@
return mString;
}
+inline std::string String16::std_string(const String16& str)
+{
+ return std::string(String8(str).string());
+}
+
inline String16& String16::operator=(const String16& other)
{
setTo(other);
diff --git a/include/utils/String8.h b/include/utils/String8.h
index 2a75b98..1d12994 100644
--- a/include/utils/String8.h
+++ b/include/utils/String8.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_STRING8_H
#define ANDROID_STRING8_H
+#include <string> // for std::string
+
#include <utils/Errors.h>
#include <utils/Unicode.h>
#include <utils/TypeHelpers.h>
@@ -49,7 +51,7 @@
String8(const String8& o);
explicit String8(const char* o);
explicit String8(const char* o, size_t numChars);
-
+
explicit String8(const String16& o);
explicit String8(const char16_t* o);
explicit String8(const char16_t* o, size_t numChars);
@@ -63,12 +65,13 @@
static String8 formatV(const char* fmt, va_list args);
inline const char* string() const;
+ static inline std::string std_string(const String8& str);
inline size_t size() const;
inline size_t bytes() const;
inline bool isEmpty() const;
-
+
size_t length() const;
-
+
void clear();
void setTo(const String8& other);
@@ -95,10 +98,10 @@
inline String8& operator=(const String8& other);
inline String8& operator=(const char* other);
-
+
inline String8& operator+=(const String8& other);
inline String8 operator+(const String8& other) const;
-
+
inline String8& operator+=(const char* other);
inline String8 operator+(const char* other) const;
@@ -110,20 +113,20 @@
inline bool operator!=(const String8& other) const;
inline bool operator>=(const String8& other) const;
inline bool operator>(const String8& other) const;
-
+
inline bool operator<(const char* other) const;
inline bool operator<=(const char* other) const;
inline bool operator==(const char* other) const;
inline bool operator!=(const char* other) const;
inline bool operator>=(const char* other) const;
inline bool operator>(const char* other) const;
-
+
inline operator const char*() const;
-
+
char* lockBuffer(size_t size);
void unlockBuffer();
status_t unlockBuffer(size_t size);
-
+
// return the index of the first byte of other in this at or after
// start, or -1 if not found
ssize_t find(const char* other, size_t start = 0) const;
@@ -261,6 +264,11 @@
return mString;
}
+inline std::string String8::std_string(const String8& str)
+{
+ return std::string(str.string());
+}
+
inline size_t String8::size() const
{
return length();
diff --git a/init/Android.mk b/init/Android.mk
index 4827fa3..2525b00 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -96,7 +96,7 @@
libc \
libselinux \
liblog \
- libmincrypt \
+ libcrypto_utils_static \
libcrypto_static \
libc++_static \
libdl \
diff --git a/init/builtins.cpp b/init/builtins.cpp
index b77f9ad..e56ec4e 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -29,6 +29,7 @@
#include <sys/socket.h>
#include <sys/mount.h>
#include <sys/resource.h>
+#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -48,7 +49,6 @@
#include <cutils/partition_utils.h>
#include <cutils/android_reboot.h>
#include <logwrap/logwrap.h>
-#include <private/android_filesystem_config.h>
#include "action.h"
#include "bootchart.h"
@@ -65,19 +65,20 @@
#define UNMOUNT_CHECK_MS 5000
#define UNMOUNT_CHECK_TIMES 10
-// System call provided by bionic but not in any header file.
-extern "C" int init_module(void *, unsigned long, const char *);
-
static const int kTerminateServiceDelayMicroSeconds = 50000;
static int insmod(const char *filename, const char *options) {
- std::string module;
- if (!read_file(filename, &module)) {
+ int fd = open(filename, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
+ if (fd == -1) {
+ ERROR("insmod: open(\"%s\") failed: %s", filename, strerror(errno));
return -1;
}
-
- // TODO: use finit_module for >= 3.8 kernels.
- return init_module(&module[0], module.size(), options);
+ int rc = syscall(__NR_finit_module, fd, options, 0);
+ if (rc == -1) {
+ ERROR("finit_module for \"%s\" failed: %s", filename, strerror(errno));
+ }
+ close(fd);
+ return rc;
}
static int __ifupdown(const char *interface, int up) {
diff --git a/init/devices.cpp b/init/devices.cpp
index 39cd706..e74140b 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -31,6 +31,8 @@
#include <sys/un.h>
#include <linux/netlink.h>
+#include <memory>
+
#include <selinux/selinux.h>
#include <selinux/label.h>
#include <selinux/android.h>
@@ -411,7 +413,7 @@
static char **get_character_device_symlinks(struct uevent *uevent)
{
const char *parent;
- char *slash;
+ const char *slash;
char **links;
int link_num = 0;
int width;
@@ -465,7 +467,7 @@
{
const char *device;
struct platform_node *pdev;
- char *slash;
+ const char *slash;
const char *type;
char buf[256];
char link_path[256];
@@ -957,10 +959,9 @@
static void coldboot(const char *path)
{
- DIR *d = opendir(path);
+ std::unique_ptr<DIR, decltype(&closedir)> d(opendir(path), closedir);
if(d) {
- do_coldboot(d);
- closedir(d);
+ do_coldboot(d.get());
}
}
diff --git a/init/init.cpp b/init/init.cpp
index 84da2b9..78c33d5 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -18,7 +18,6 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
-#include <fstream>
#include <libgen.h>
#include <paths.h>
#include <signal.h>
@@ -75,8 +74,7 @@
static char qemu[32];
-int have_console;
-std::string console_name = "/dev/console";
+std::string default_console = "/dev/console";
static time_t process_needs_restart;
const char *ENV[32];
@@ -251,100 +249,6 @@
return result;
}
-static void security_failure() {
- ERROR("Security failure; rebooting into recovery mode...\n");
- android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
- while (true) { pause(); } // never reached
-}
-
-#define MMAP_RND_PATH "/proc/sys/vm/mmap_rnd_bits"
-#define MMAP_RND_COMPAT_PATH "/proc/sys/vm/mmap_rnd_compat_bits"
-
-/* __attribute__((unused)) due to lack of mips support: see mips block
- * in set_mmap_rnd_bits_action */
-static bool __attribute__((unused)) set_mmap_rnd_bits_min(int start, int min, bool compat) {
- std::string path;
- if (compat) {
- path = MMAP_RND_COMPAT_PATH;
- } else {
- path = MMAP_RND_PATH;
- }
- std::ifstream inf(path, std::fstream::in);
- if (!inf) {
- return false;
- }
- while (start >= min) {
- // try to write out new value
- std::string str_val = std::to_string(start);
- std::ofstream of(path, std::fstream::out);
- if (!of) {
- return false;
- }
- of << str_val << std::endl;
- of.close();
-
- // check to make sure it was recorded
- inf.seekg(0);
- std::string str_rec;
- inf >> str_rec;
- if (str_val.compare(str_rec) == 0) {
- break;
- }
- start--;
- }
- inf.close();
- return (start >= min);
-}
-
-/*
- * Set /proc/sys/vm/mmap_rnd_bits and potentially
- * /proc/sys/vm/mmap_rnd_compat_bits to the maximum supported values.
- * Returns -1 if unable to set these to an acceptable value. Apply
- * upstream patch-sets https://lkml.org/lkml/2015/12/21/337 and
- * https://lkml.org/lkml/2016/2/4/831 to enable this.
- */
-static int set_mmap_rnd_bits_action(const std::vector<std::string>& args)
-{
- int ret = -1;
-
- /* values are arch-dependent */
-#if defined(__aarch64__)
- /* arm64 supports 18 - 33 bits depending on pagesize and VA_SIZE */
- if (set_mmap_rnd_bits_min(33, 24, false)
- && set_mmap_rnd_bits_min(16, 16, true)) {
- ret = 0;
- }
-#elif defined(__x86_64__)
- /* x86_64 supports 28 - 32 bits */
- if (set_mmap_rnd_bits_min(32, 32, false)
- && set_mmap_rnd_bits_min(16, 16, true)) {
- ret = 0;
- }
-#elif defined(__arm__) || defined(__i386__)
- /* check to see if we're running on 64-bit kernel */
- bool h64 = !access(MMAP_RND_COMPAT_PATH, F_OK);
- /* supported 32-bit architecture must have 16 bits set */
- if (set_mmap_rnd_bits_min(16, 16, h64)) {
- ret = 0;
- }
-#elif defined(__mips__) || defined(__mips64__)
- // TODO: add mips support b/27788820
- ret = 0;
-#else
- ERROR("Unknown architecture\n");
-#endif
-
-#ifdef __BRILLO__
- // TODO: b/27794137
- ret = 0;
-#endif
- if (ret == -1) {
- ERROR("Unable to set adequate mmap entropy value!\n");
- security_failure();
- }
- return ret;
-}
-
static int keychord_init_action(const std::vector<std::string>& args)
{
keychord_init();
@@ -355,36 +259,8 @@
{
std::string console = property_get("ro.boot.console");
if (!console.empty()) {
- console_name = "/dev/" + console;
+ default_console = "/dev/" + console;
}
-
- int fd = open(console_name.c_str(), O_RDWR | O_CLOEXEC);
- if (fd >= 0)
- have_console = 1;
- close(fd);
-
- fd = open("/dev/tty0", O_WRONLY | O_CLOEXEC);
- if (fd >= 0) {
- const char *msg;
- msg = "\n"
- "\n"
- "\n"
- "\n"
- "\n"
- "\n"
- "\n" // console is 40 cols x 30 lines
- "\n"
- "\n"
- "\n"
- "\n"
- "\n"
- "\n"
- "\n"
- " A N D R O I D ";
- write(fd, msg, strlen(msg));
- close(fd);
- }
-
return 0;
}
@@ -515,24 +391,6 @@
return true;
}
-int selinux_reload_policy(void)
-{
- INFO("SELinux: Attempting to reload policy files\n");
-
- if (selinux_android_reload_policy() == -1) {
- return -1;
- }
-
- if (sehandle)
- selabel_close(sehandle);
-
- if (sehandle_prop)
- selabel_close(sehandle_prop);
-
- selinux_init_all_handles();
- return 0;
-}
-
static int audit_callback(void *data, security_class_t /*cls*/, char *buf, size_t len) {
property_audit_data *d = reinterpret_cast<property_audit_data*>(data);
@@ -547,6 +405,12 @@
return 0;
}
+static void security_failure() {
+ ERROR("Security failure; rebooting into recovery mode...\n");
+ android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
+ while (true) { pause(); } // never reached
+}
+
static void selinux_initialize(bool in_kernel_domain) {
Timer t;
@@ -610,6 +474,7 @@
#define MAKE_STR(x) __STRING(x)
mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
mount("sysfs", "/sys", "sysfs", 0, NULL);
+ mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
}
// We must have some place other than / to create the device nodes for
@@ -695,7 +560,6 @@
am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
// ... so that we can start queuing up actions that require stuff from /dev.
am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
- am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits");
am.QueueBuiltinAction(keychord_init_action, "keychord_init");
am.QueueBuiltinAction(console_init_action, "console_init");
diff --git a/init/init.h b/init/init.h
index 345d442..0019337 100644
--- a/init/init.h
+++ b/init/init.h
@@ -26,8 +26,7 @@
extern const char *ENV[32];
extern bool waiting_for_exec;
-extern int have_console;
-extern std::string console_name;
+extern std::string default_console;
extern struct selabel_handle *sehandle;
extern struct selabel_handle *sehandle_prop;
@@ -35,8 +34,6 @@
void property_changed(const char *name, const char *value);
-int selinux_reload_policy(void);
-
void register_epoll_handler(int fd, void (*fn)());
int add_environment(const char* key, const char* val);
diff --git a/init/parser.cpp b/init/parser.cpp
index 8193729..ae103ec 100644
--- a/init/parser.cpp
+++ b/init/parser.cpp
@@ -12,7 +12,7 @@
char buf[128];
int off;
- snprintf(buf, 128, "%s: %d: ", state->filename, state->line);
+ snprintf(buf, sizeof(buf), "%s: %d: ", state->filename, state->line);
buf[127] = 0;
off = strlen(buf);
diff --git a/init/perfboot.py b/init/perfboot.py
index 91e6c2b..713290b 100755
--- a/init/perfboot.py
+++ b/init/perfboot.py
@@ -191,9 +191,9 @@
def init_perf(device, output, record_list, tags):
device.wait()
- build_type = device.get_prop('ro.build.type')
+ debuggable = device.get_prop('ro.debuggable')
original_dropbox_max_files = None
- if build_type != 'user':
+ if debuggable == '1':
# Workaround for Dropbox issue (http://b/20890386).
original_dropbox_max_files = disable_dropbox(device)
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 5c1ae79..c617dc6 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -41,7 +41,6 @@
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/mman.h>
-#include <private/android_filesystem_config.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
@@ -175,11 +174,7 @@
if (!is_legal_property_name(name, namelen)) return -1;
if (valuelen >= PROP_VALUE_MAX) return -1;
- if (strcmp("selinux.reload_policy", name) == 0 && strcmp("1", value) == 0) {
- if (selinux_reload_policy() != 0) {
- ERROR("Failed to reload policy\n");
- }
- } else if (strcmp("selinux.restorecon_recursive", name) == 0 && valuelen > 0) {
+ if (strcmp("selinux.restorecon_recursive", name) == 0 && valuelen > 0) {
if (restorecon_recursive(value) != 0) {
ERROR("Failed to restorecon_recursive %s\n", value);
}
diff --git a/init/readme.txt b/init/readme.txt
index ef85ccf..aa372eb 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -115,6 +115,13 @@
Options are modifiers to services. They affect how and when init
runs the service.
+console [<console>]
+ This service needs a console. The optional second parameter chooses a
+ specific console instead of the default. The default "/dev/console" can
+ be changed by setting the "androidboot.console" kernel parameter. In
+ all cases the leading "/dev/" should be omitted, so "/dev/tty0" would be
+ specified as just "console tty0".
+
critical
This is a device-critical service. If it exits more than four times in
four minutes, the device will reboot into recovery mode.
diff --git a/init/service.cpp b/init/service.cpp
index f1ffa18..f5b8b00 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -172,6 +172,7 @@
bool Service::HandleConsole(const std::vector<std::string>& args, std::string* err) {
flags_ |= SVC_CONSOLE;
+ console_ = args.size() > 1 ? "/dev/" + args[1] : "";
return true;
}
@@ -282,7 +283,7 @@
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
static const Map option_handlers = {
{"class", {1, 1, &Service::HandleClass}},
- {"console", {0, 0, &Service::HandleConsole}},
+ {"console", {0, 1, &Service::HandleConsole}},
{"critical", {0, 0, &Service::HandleCritical}},
{"disabled", {0, 0, &Service::HandleDisabled}},
{"group", {1, NR_SVC_SUPP_GIDS + 1, &Service::HandleGroup}},
@@ -329,10 +330,18 @@
}
bool needs_console = (flags_ & SVC_CONSOLE);
- if (needs_console && !have_console) {
- ERROR("service '%s' requires console\n", name_.c_str());
- flags_ |= SVC_DISABLED;
- return false;
+ if (needs_console) {
+ if (console_.empty()) {
+ console_ = default_console;
+ }
+
+ bool have_console = (open(console_.c_str(), O_RDWR | O_CLOEXEC) != -1);
+ if (!have_console) {
+ ERROR("service '%s' couldn't open console '%s': %s\n",
+ name_.c_str(), console_.c_str(), strerror(errno));
+ flags_ |= SVC_DISABLED;
+ return false;
+ }
}
struct stat sb;
@@ -591,10 +600,8 @@
}
void Service::OpenConsole() const {
- int fd;
- if ((fd = open(console_name.c_str(), O_RDWR)) < 0) {
- fd = open("/dev/null", O_RDWR);
- }
+ int fd = open(console_.c_str(), O_RDWR);
+ if (fd == -1) fd = open("/dev/null", O_RDWR);
ioctl(fd, TIOCSCTTY, 0);
dup2(fd, 0);
dup2(fd, 1);
diff --git a/init/service.h b/init/service.h
index d9d18ef..d6ce664 100644
--- a/init/service.h
+++ b/init/service.h
@@ -128,6 +128,7 @@
std::string name_;
std::string classname_;
+ std::string console_;
unsigned flags_;
pid_t pid_;
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 249739b..73b2136 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -16,14 +16,17 @@
#include <ctype.h>
#include <fcntl.h>
+#include <grp.h>
#include <poll.h>
+#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
+
#include <android-base/stringprintf.h>
-#include <private/android_filesystem_config.h>
#include <selinux/selinux.h>
#include "ueventd.h"
@@ -84,15 +87,6 @@
return 0;
}
-static int get_android_id(const char *id)
-{
- unsigned int i;
- for (i = 0; i < ARRAY_SIZE(android_ids); i++)
- if (!strcmp(id, android_ids[i].name))
- return android_ids[i].aid;
- return -1;
-}
-
void set_device_permission(int nargs, char **args)
{
char *name;
@@ -103,7 +97,6 @@
int prefix = 0;
int wildcard = 0;
char *endptr;
- int ret;
char *tmp = 0;
if (nargs == 0)
@@ -151,21 +144,21 @@
return;
}
- ret = get_android_id(args[2]);
- if (ret < 0) {
+ struct passwd* pwd = getpwnam(args[2]);
+ if (!pwd) {
ERROR("invalid uid '%s'\n", args[2]);
free(tmp);
return;
}
- uid = ret;
+ uid = pwd->pw_uid;
- ret = get_android_id(args[3]);
- if (ret < 0) {
+ struct group* grp = getgrnam(args[3]);
+ if (!grp) {
ERROR("invalid gid '%s'\n", args[3]);
free(tmp);
return;
}
- gid = ret;
+ gid = grp->gr_gid;
add_dev_perms(name, attr, perm, uid, gid, prefix, wildcard);
free(tmp);
diff --git a/init/util.cpp b/init/util.cpp
index 84b4155..750e040 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -23,6 +23,7 @@
#include <errno.h>
#include <time.h>
#include <ftw.h>
+#include <pwd.h>
#include <selinux/label.h>
#include <selinux/android.h>
@@ -39,38 +40,24 @@
#include <cutils/sockets.h>
#include <android-base/stringprintf.h>
-#include <private/android_filesystem_config.h>
-
#include "init.h"
#include "log.h"
#include "property_service.h"
#include "util.h"
-/*
- * android_name_to_id - returns the integer uid/gid associated with the given
- * name, or UINT_MAX on error.
- */
-static unsigned int android_name_to_id(const char *name)
-{
- const struct android_id_info *info = android_ids;
- unsigned int n;
-
- for (n = 0; n < android_id_count; n++) {
- if (!strcmp(info[n].name, name))
- return info[n].aid;
- }
-
- return UINT_MAX;
-}
-
static unsigned int do_decode_uid(const char *s)
{
unsigned int v;
if (!s || *s == '\0')
return UINT_MAX;
- if (isalpha(s[0]))
- return android_name_to_id(s);
+
+ if (isalpha(s[0])) {
+ struct passwd* pwd = getpwnam(s);
+ if (!pwd)
+ return UINT_MAX;
+ return pwd->pw_uid;
+ }
errno = 0;
v = (unsigned int) strtoul(s, 0, 0);
@@ -355,7 +342,7 @@
{
int ret;
char buf[256];
- char *slash;
+ const char *slash;
int width;
slash = strrchr(newpath, '/');
@@ -401,20 +388,18 @@
void open_devnull_stdio(void)
{
- // Try to avoid the mknod() call if we can. Since SELinux makes
- // a /dev/null replacement available for free, let's use it.
int fd = open("/sys/fs/selinux/null", O_RDWR);
if (fd == -1) {
- // OOPS, /sys/fs/selinux/null isn't available, likely because
- // /sys/fs/selinux isn't mounted. Fall back to mknod.
- static const char *name = "/dev/__null__";
- if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) {
- fd = open(name, O_RDWR);
- unlink(name);
- }
- if (fd == -1) {
- exit(1);
- }
+ /* Fail silently.
+ * stdout/stderr isn't available, and because
+ * klog_init() is called after open_devnull_stdio(), we can't
+ * log to dmesg. Reordering klog_init() to be called before
+ * open_devnull_stdio() isn't an option either, as then klog_fd
+ * will be assigned 0 or 1, which will end up getting clobbered
+ * by the code below. There's nowhere good to log.
+ */
+
+ exit(1);
}
dup2(fd, 0);
diff --git a/libbacktrace/Android.mk b/libbacktrace/Android.mk
index ee25e08..632b1b6 100644
--- a/libbacktrace/Android.mk
+++ b/libbacktrace/Android.mk
@@ -71,14 +71,22 @@
build_type := host
libbacktrace_multilib := both
include $(LOCAL_PATH)/Android.build.mk
+
+libbacktrace_shared_libraries :=
+
libbacktrace_static_libraries := \
libbase \
liblog \
libunwind \
+ liblzma \
+module := libbacktrace
+build_type := target
build_target := STATIC_LIBRARY
include $(LOCAL_PATH)/Android.build.mk
-libbacktrace_static_libraries :=
+build_type := host
+libbacktrace_multilib := both
+include $(LOCAL_PATH)/Android.build.mk
#-------------------------------------------------------------------------
# The libbacktrace_offline shared library.
diff --git a/libbacktrace/BacktraceMap.cpp b/libbacktrace/BacktraceMap.cpp
index ba86632..19551dc 100644
--- a/libbacktrace/BacktraceMap.cpp
+++ b/libbacktrace/BacktraceMap.cpp
@@ -15,6 +15,7 @@
*/
#include <ctype.h>
+#include <inttypes.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
@@ -46,8 +47,8 @@
}
bool BacktraceMap::ParseLine(const char* line, backtrace_map_t* map) {
- unsigned long int start;
- unsigned long int end;
+ uint64_t start;
+ uint64_t end;
char permissions[5];
int name_pos;
@@ -56,14 +57,14 @@
// __TEXT 0009f000-000a1000 [ 8K 8K] r-x/rwx SM=COW /Volumes/android/dalvik-dev/out/host/darwin-x86/bin/libcorkscrew_test\n
// 012345678901234567890123456789012345678901234567890123456789
// 0 1 2 3 4 5
- if (sscanf(line, "%*21c %lx-%lx [%*13c] %3c/%*3c SM=%*3c %n",
+ if (sscanf(line, "%*21c %" SCNx64 "-%" SCNx64 " [%*13c] %3c/%*3c SM=%*3c %n",
&start, &end, permissions, &name_pos) != 3) {
#else
// Linux /proc/<pid>/maps lines:
// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /system/lib/libcomposer.so\n
// 012345678901234567890123456789012345678901234567890123456789
// 0 1 2 3 4 5
- if (sscanf(line, "%lx-%lx %4s %*x %*x:%*x %*d %n",
+ if (sscanf(line, "%" SCNx64 "-%" SCNx64 " %4s %*x %*x:%*x %*d %n",
&start, &end, permissions, &name_pos) != 3) {
#endif
return false;
diff --git a/libbacktrace/GetPss.cpp b/libbacktrace/GetPss.cpp
index 09a721d..b4dc48d 100644
--- a/libbacktrace/GetPss.cpp
+++ b/libbacktrace/GetPss.cpp
@@ -33,7 +33,7 @@
#define PAGEMAP_SWAP_OFFSET(x) (_BITS(x, 5, 50))
#define PAGEMAP_SWAP_TYPE(x) (_BITS(x, 0, 5))
-static bool ReadData(int fd, unsigned long place, uint64_t *data) {
+static bool ReadData(int fd, off_t place, uint64_t *data) {
if (lseek(fd, place * sizeof(uint64_t), SEEK_SET) < 0) {
return false;
}
@@ -71,12 +71,13 @@
total_pss = 0;
break;
}
- for (size_t page = start/pagesize; page < end/pagesize; page++) {
+ for (off_t page = static_cast<off_t>(start/pagesize);
+ page < static_cast<off_t>(end/pagesize); page++) {
uint64_t data;
if (ReadData(pagemap_fd, page, &data)) {
if (PAGEMAP_PRESENT(data) && !PAGEMAP_SWAPPED(data)) {
uint64_t count;
- if (ReadData(pagecount_fd, PAGEMAP_PFN(data), &count)) {
+ if (ReadData(pagecount_fd, static_cast<off_t>(PAGEMAP_PFN(data)), &count)) {
total_pss += (count >= 1) ? pagesize / count : 0;
}
}
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index f6b2591..df6c6c1 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -414,17 +414,16 @@
char task_path[128];
snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid);
- DIR* tasks_dir = opendir(task_path);
+ std::unique_ptr<DIR, decltype(&closedir)> tasks_dir(opendir(task_path), closedir);
ASSERT_TRUE(tasks_dir != nullptr);
struct dirent* entry;
- while ((entry = readdir(tasks_dir)) != nullptr) {
+ while ((entry = readdir(tasks_dir.get())) != nullptr) {
char* end;
pid_t tid = strtoul(entry->d_name, &end, 10);
if (*end == '\0') {
threads->push_back(tid);
}
}
- closedir(tasks_dir);
}
TEST(libbacktrace, ptrace_threads) {
@@ -1445,9 +1444,9 @@
}
size_t new_pss = GetPssBytes();
ASSERT_TRUE(new_pss != 0);
- size_t abs_diff = (new_pss > stable_pss) ? new_pss - stable_pss : stable_pss - new_pss;
- // As long as the new pss is within a certain amount, consider everything okay.
- ASSERT_LE(abs_diff, MAX_LEAK_BYTES);
+ if (new_pss > stable_pss) {
+ ASSERT_LE(new_pss - stable_pss, MAX_LEAK_BYTES);
+ }
}
TEST(libbacktrace, check_for_leak_local) {
diff --git a/libbinderwrapper/real_binder_wrapper.cc b/libbinderwrapper/real_binder_wrapper.cc
index 1c51822..f93f183 100644
--- a/libbinderwrapper/real_binder_wrapper.cc
+++ b/libbinderwrapper/real_binder_wrapper.cc
@@ -29,7 +29,7 @@
// be awkward.
class RealBinderWrapper::DeathRecipient : public IBinder::DeathRecipient {
public:
- explicit DeathRecipient(const base::Closure& callback)
+ explicit DeathRecipient(const ::base::Closure& callback)
: callback_(callback) {}
~DeathRecipient() = default;
@@ -40,7 +40,7 @@
private:
// Callback to run in response to binder death.
- base::Closure callback_;
+ ::base::Closure callback_;
DISALLOW_COPY_AND_ASSIGN(DeathRecipient);
};
@@ -85,7 +85,7 @@
bool RealBinderWrapper::RegisterForDeathNotifications(
const sp<IBinder>& binder,
- const base::Closure& callback) {
+ const ::base::Closure& callback) {
sp<DeathRecipient> recipient(new DeathRecipient(callback));
if (binder->linkToDeath(recipient) != OK) {
LOG(ERROR) << "Failed to register for death notifications on "
diff --git a/libbinderwrapper/real_binder_wrapper.h b/libbinderwrapper/real_binder_wrapper.h
index ea08371..1675432 100644
--- a/libbinderwrapper/real_binder_wrapper.h
+++ b/libbinderwrapper/real_binder_wrapper.h
@@ -36,7 +36,7 @@
const sp<IBinder>& binder) override;
sp<BBinder> CreateLocalBinder() override;
bool RegisterForDeathNotifications(const sp<IBinder>& binder,
- const base::Closure& callback) override;
+ const ::base::Closure& callback) override;
bool UnregisterForDeathNotifications(const sp<IBinder>& binder) override;
uid_t GetCallingUid() override;
pid_t GetCallingPid() override;
diff --git a/libbinderwrapper/stub_binder_wrapper.cc b/libbinderwrapper/stub_binder_wrapper.cc
index 87c6ab7..8e75f62 100644
--- a/libbinderwrapper/stub_binder_wrapper.cc
+++ b/libbinderwrapper/stub_binder_wrapper.cc
@@ -64,7 +64,7 @@
bool StubBinderWrapper::RegisterForDeathNotifications(
const sp<IBinder>& binder,
- const base::Closure& callback) {
+ const ::base::Closure& callback) {
death_callbacks_[binder] = callback;
return true;
}
diff --git a/libcrypto_utils/Android.mk b/libcrypto_utils/Android.mk
new file mode 100644
index 0000000..5e9763f
--- /dev/null
+++ b/libcrypto_utils/Android.mk
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libcrypto_utils
+LOCAL_SRC_FILES := android_pubkey.c
+LOCAL_CFLAGS := -Wall -Werror -Wextra -std=c99
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_SHARED_LIBRARIES := libcrypto
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libcrypto_utils
+LOCAL_SRC_FILES := android_pubkey.c
+LOCAL_CFLAGS := -Wall -Werror -Wextra -std=c99
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_SHARED_LIBRARIES := libcrypto-host
+include $(BUILD_HOST_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libcrypto_utils_static
+LOCAL_SRC_FILES := android_pubkey.c
+LOCAL_CFLAGS := -Wall -Werror -Wextra -std=c99
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_STATIC_LIBRARIES := libcrypto_static
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libcrypto_utils_static
+LOCAL_MODULE_HOST_OS := darwin linux windows
+LOCAL_SRC_FILES := android_pubkey.c
+LOCAL_CFLAGS := -Wall -Werror -Wextra -std=c99
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_STATIC_LIBRARIES := libcrypto_static
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libcrypto_utils/android_pubkey.c b/libcrypto_utils/android_pubkey.c
new file mode 100644
index 0000000..3052e52
--- /dev/null
+++ b/libcrypto_utils/android_pubkey.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <crypto_utils/android_pubkey.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+
+// Better safe than sorry.
+#if (ANDROID_PUBKEY_MODULUS_SIZE % 4) != 0
+#error RSA modulus size must be multiple of the word size!
+#endif
+
+// Size of the RSA modulus in words.
+#define ANDROID_PUBKEY_MODULUS_SIZE_WORDS (ANDROID_PUBKEY_MODULUS_SIZE / 4)
+
+// This file implements encoding and decoding logic for Android's custom RSA
+// public key binary format. Public keys are stored as a sequence of
+// little-endian 32 bit words. Note that Android only supports little-endian
+// processors, so we don't do any byte order conversions when parsing the binary
+// struct.
+typedef struct RSAPublicKey {
+ // Modulus length. This must be ANDROID_PUBKEY_MODULUS_SIZE.
+ uint32_t modulus_size_words;
+
+ // Precomputed montgomery parameter: -1 / n[0] mod 2^32
+ uint32_t n0inv;
+
+ // RSA modulus as a little-endian array.
+ uint8_t modulus[ANDROID_PUBKEY_MODULUS_SIZE];
+
+ // Montgomery parameter R^2 as a little-endian array of little-endian words.
+ uint8_t rr[ANDROID_PUBKEY_MODULUS_SIZE];
+
+ // RSA modulus: 3 or 65537
+ uint32_t exponent;
+} RSAPublicKey;
+
+// Reverses byte order in |buffer|.
+static void reverse_bytes(uint8_t* buffer, size_t size) {
+ for (size_t i = 0; i < (size + 1) / 2; ++i) {
+ uint8_t tmp = buffer[i];
+ buffer[i] = buffer[size - i - 1];
+ buffer[size - i - 1] = tmp;
+ }
+}
+
+bool android_pubkey_decode(const uint8_t* key_buffer, size_t size, RSA** key) {
+ const RSAPublicKey* key_struct = (RSAPublicKey*)key_buffer;
+ bool ret = false;
+ uint8_t modulus_buffer[ANDROID_PUBKEY_MODULUS_SIZE];
+ RSA* new_key = RSA_new();
+ if (!new_key) {
+ goto cleanup;
+ }
+
+ // Check |size| is large enough and the modulus size is correct.
+ if (size < sizeof(RSAPublicKey)) {
+ goto cleanup;
+ }
+ if (key_struct->modulus_size_words != ANDROID_PUBKEY_MODULUS_SIZE_WORDS) {
+ goto cleanup;
+ }
+
+ // Convert the modulus to big-endian byte order as expected by BN_bin2bn.
+ memcpy(modulus_buffer, key_struct->modulus, sizeof(modulus_buffer));
+ reverse_bytes(modulus_buffer, sizeof(modulus_buffer));
+ new_key->n = BN_bin2bn(modulus_buffer, sizeof(modulus_buffer), NULL);
+ if (!new_key->n) {
+ goto cleanup;
+ }
+
+ // Read the exponent.
+ new_key->e = BN_new();
+ if (!new_key->e || !BN_set_word(new_key->e, key_struct->exponent)) {
+ goto cleanup;
+ }
+
+ // Note that we don't extract the montgomery parameters n0inv and rr from
+ // the RSAPublicKey structure. They assume a word size of 32 bits, but
+ // BoringSSL may use a word size of 64 bits internally, so we're lacking the
+ // top 32 bits of n0inv in general. For now, we just ignore the parameters
+ // and have BoringSSL recompute them internally. More sophisticated logic can
+ // be added here if/when we want the additional speedup from using the
+ // pre-computed montgomery parameters.
+
+ *key = new_key;
+ ret = true;
+
+cleanup:
+ if (!ret && new_key) {
+ RSA_free(new_key);
+ }
+ return ret;
+}
+
+static bool android_pubkey_encode_bignum(const BIGNUM* num, uint8_t* buffer) {
+ if (!BN_bn2bin_padded(buffer, ANDROID_PUBKEY_MODULUS_SIZE, num)) {
+ return false;
+ }
+
+ reverse_bytes(buffer, ANDROID_PUBKEY_MODULUS_SIZE);
+ return true;
+}
+
+bool android_pubkey_encode(const RSA* key, uint8_t* key_buffer, size_t size) {
+ RSAPublicKey* key_struct = (RSAPublicKey*)key_buffer;
+ bool ret = false;
+ BN_CTX* ctx = BN_CTX_new();
+ BIGNUM* r32 = BN_new();
+ BIGNUM* n0inv = BN_new();
+ BIGNUM* rr = BN_new();
+
+ if (sizeof(RSAPublicKey) > size ||
+ RSA_size(key) != ANDROID_PUBKEY_MODULUS_SIZE) {
+ goto cleanup;
+ }
+
+ // Store the modulus size.
+ key_struct->modulus_size_words = ANDROID_PUBKEY_MODULUS_SIZE_WORDS;
+
+ // Compute and store n0inv = -1 / N[0] mod 2^32.
+ if (!ctx || !r32 || !n0inv || !BN_set_bit(r32, 32) ||
+ !BN_mod(n0inv, key->n, r32, ctx) ||
+ !BN_mod_inverse(n0inv, n0inv, r32, ctx) || !BN_sub(n0inv, r32, n0inv)) {
+ goto cleanup;
+ }
+ key_struct->n0inv = (uint32_t)BN_get_word(n0inv);
+
+ // Store the modulus.
+ if (!android_pubkey_encode_bignum(key->n, key_struct->modulus)) {
+ goto cleanup;
+ }
+
+ // Compute and store rr = (2^(rsa_size)) ^ 2 mod N.
+ if (!ctx || !rr || !BN_set_bit(rr, ANDROID_PUBKEY_MODULUS_SIZE * 8) ||
+ !BN_mod_sqr(rr, rr, key->n, ctx) ||
+ !android_pubkey_encode_bignum(rr, key_struct->rr)) {
+ goto cleanup;
+ }
+
+ // Store the exponent.
+ key_struct->exponent = (uint32_t)BN_get_word(key->e);
+
+ ret = true;
+
+cleanup:
+ BN_free(rr);
+ BN_free(n0inv);
+ BN_free(r32);
+ BN_CTX_free(ctx);
+ return ret;
+}
diff --git a/libcrypto_utils/include/crypto_utils/android_pubkey.h b/libcrypto_utils/include/crypto_utils/android_pubkey.h
new file mode 100644
index 0000000..1045eba
--- /dev/null
+++ b/libcrypto_utils/include/crypto_utils/android_pubkey.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CRYPTO_UTILS_ANDROID_PUBKEY_H
+#define CRYPTO_UTILS_ANDROID_PUBKEY_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <openssl/rsa.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Size of an RSA modulus such as an encrypted block or a signature.
+#define ANDROID_PUBKEY_MODULUS_SIZE (2048 / 8)
+
+// Size of an encoded RSA key.
+#define ANDROID_PUBKEY_ENCODED_SIZE \
+ (3 * sizeof(uint32_t) + 2 * ANDROID_PUBKEY_MODULUS_SIZE)
+
+/* Allocates a new RSA |key| object, decodes a public RSA key stored in
+ * Android's custom binary format from |key_buffer| and sets the key parameters
+ * in |key|. |size| specifies the size of the key buffer and must be at least
+ * |ANDROID_PUBKEY_ENCODED_SIZE|. The resulting |*key| can be used with the
+ * standard BoringSSL API to perform public operations.
+ *
+ * Returns true if successful, in which case the caller receives ownership of
+ * the |*key| object, i.e. needs to call RSA_free() when done with it. If there
+ * is an error, |key| is left untouched and the return value will be false.
+ */
+bool android_pubkey_decode(const uint8_t* key_buffer, size_t size, RSA** key);
+
+/* Encodes |key| in the Android RSA public key binary format and stores the
+ * bytes in |key_buffer|. |key_buffer| should be of size at least
+ * |ANDROID_PUBKEY_ENCODED_SIZE|.
+ *
+ * Returns true if successful, false on error.
+ */
+bool android_pubkey_encode(const RSA* key, uint8_t* key_buffer, size_t size);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // CRYPTO_UTILS_ANDROID_PUBKEY_H
diff --git a/libmincrypt/tools/Android.mk b/libcrypto_utils/tests/Android.mk
similarity index 68%
rename from libmincrypt/tools/Android.mk
rename to libcrypto_utils/tests/Android.mk
index 3154914..dad82f7 100644
--- a/libmincrypt/tools/Android.mk
+++ b/libcrypto_utils/tests/Android.mk
@@ -1,4 +1,5 @@
-# Copyright (C) 2008 The Android Open Source Project
+#
+# Copyright (C) 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -11,12 +12,13 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_MODULE := dumpkey
-LOCAL_SRC_FILES := DumpPublicKey.java
-LOCAL_JAR_MANIFEST := DumpPublicKey.mf
-LOCAL_STATIC_JAVA_LIBRARIES := bouncycastle-host
-include $(BUILD_HOST_JAVA_LIBRARY)
+LOCAL_MODULE := libcrypto_utils_test
+LOCAL_SRC_FILES := android_pubkey_test.cpp
+LOCAL_CFLAGS := -Wall -Werror -Wextra -std=c++11
+LOCAL_SHARED_LIBRARIES := libcrypto_utils libcrypto-host
+include $(BUILD_HOST_NATIVE_TEST)
diff --git a/libcrypto_utils/tests/android_pubkey_test.cpp b/libcrypto_utils/tests/android_pubkey_test.cpp
new file mode 100644
index 0000000..f8c2e0c
--- /dev/null
+++ b/libcrypto_utils/tests/android_pubkey_test.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <crypto_utils/android_pubkey.h>
+
+#include <string.h>
+
+#include <memory>
+
+#include <openssl/obj_mac.h>
+#include <openssl/rsa.h>
+
+#include <gtest/gtest.h>
+
+// Test digest to verify.
+const uint8_t kDigest[] = {
+ 0x31, 0x5f, 0x5b, 0xdb, 0x76, 0xd0, 0x78, 0xc4, 0x3b, 0x8a, 0xc0,
+ 0x06, 0x4e, 0x4a, 0x01, 0x64, 0x61, 0x2b, 0x1f, 0xce, 0x77, 0xc8,
+ 0x69, 0x34, 0x5b, 0xfc, 0x94, 0xc7, 0x58, 0x94, 0xed, 0xd3,
+};
+
+// 2048 RSA test key.
+const uint8_t kKey2048[ANDROID_PUBKEY_ENCODED_SIZE] = {
+ 0x40, 0x00, 0x00, 0x00, 0x05, 0x75, 0x61, 0xd1, 0x33, 0xf0, 0x2d, 0x12,
+ 0x45, 0xfb, 0xae, 0x07, 0x02, 0x15, 0x4f, 0x3a, 0x2b, 0xa3, 0xbc, 0x49,
+ 0xbd, 0x14, 0x07, 0xa0, 0xc0, 0x9f, 0x0c, 0x52, 0x60, 0x77, 0x9f, 0xa2,
+ 0x31, 0xd0, 0xa7, 0xfb, 0x7e, 0xde, 0xfb, 0xc9, 0x05, 0xc0, 0x97, 0xf7,
+ 0x74, 0x99, 0xe6, 0xd1, 0x08, 0xa6, 0xc2, 0x59, 0x5a, 0xd8, 0x37, 0x1d,
+ 0xe0, 0x48, 0x5e, 0x63, 0x44, 0x04, 0x8b, 0x05, 0x20, 0xf6, 0x25, 0x67,
+ 0x38, 0xb2, 0xb6, 0xf9, 0xbe, 0xb6, 0x1d, 0x7f, 0x1b, 0x71, 0x8a, 0xeb,
+ 0xb7, 0xf8, 0x01, 0xc1, 0x5e, 0xf7, 0xfe, 0x48, 0x08, 0x27, 0x0f, 0x27,
+ 0x2a, 0x64, 0x1a, 0x43, 0x8d, 0xcf, 0x5a, 0x33, 0x5c, 0x18, 0xc5, 0xf4,
+ 0xe7, 0xfe, 0xee, 0xd3, 0x12, 0x62, 0xad, 0x61, 0x78, 0x9a, 0x03, 0xb0,
+ 0xaf, 0xab, 0x91, 0x57, 0x46, 0xbf, 0x18, 0xc6, 0xbc, 0x0c, 0x6b, 0x55,
+ 0xcd, 0xda, 0xc4, 0xcc, 0x98, 0x46, 0x91, 0x99, 0xbc, 0xa3, 0xca, 0x6c,
+ 0x86, 0xa6, 0x1c, 0x8f, 0xca, 0xf8, 0xf6, 0x8a, 0x00, 0x8e, 0x05, 0xd7,
+ 0x13, 0x43, 0xe2, 0xf2, 0x1a, 0x13, 0xf3, 0x50, 0x13, 0xa4, 0xf2, 0x4e,
+ 0x41, 0xb1, 0x36, 0x78, 0x55, 0x4c, 0x5e, 0x27, 0xc5, 0xc0, 0x4b, 0xd8,
+ 0x93, 0xaa, 0x7e, 0xf0, 0x90, 0x08, 0x10, 0x26, 0x72, 0x6d, 0xb9, 0x21,
+ 0xae, 0x4d, 0x01, 0x4b, 0x55, 0x1d, 0xe7, 0x1e, 0x5e, 0x31, 0x6e, 0x62,
+ 0xd1, 0x33, 0x26, 0xcb, 0xdb, 0xfe, 0x72, 0x98, 0xc8, 0x06, 0x1c, 0x12,
+ 0xdf, 0xfc, 0x74, 0xe5, 0x7a, 0x6f, 0xf5, 0xa3, 0x63, 0x08, 0xe3, 0x02,
+ 0x68, 0x4d, 0x7c, 0x70, 0x05, 0xec, 0x95, 0x7e, 0x24, 0xa4, 0xbc, 0x4c,
+ 0xcd, 0x39, 0x14, 0xb5, 0x2a, 0x8f, 0xc1, 0xe3, 0x4e, 0xfa, 0xf8, 0x70,
+ 0x50, 0x8f, 0xd5, 0x8e, 0xc7, 0xb5, 0x32, 0x89, 0x4d, 0xbb, 0x6a, 0xc1,
+ 0xc1, 0xa2, 0x42, 0x57, 0x57, 0xbd, 0x2a, 0xdc, 0xa6, 0xfd, 0xc8, 0x86,
+ 0x44, 0x6a, 0x03, 0x5d, 0x4d, 0x28, 0xe1, 0xde, 0xb4, 0xa9, 0xa5, 0x03,
+ 0x61, 0x7a, 0x5f, 0xb1, 0x09, 0x17, 0x2b, 0x9c, 0xa2, 0x54, 0x28, 0xad,
+ 0x34, 0xc9, 0x5f, 0x6c, 0x9f, 0xb8, 0xd2, 0xa9, 0x78, 0xa7, 0xaa, 0xb3,
+ 0x11, 0x2f, 0x65, 0x9b, 0x4e, 0x67, 0x0c, 0xcc, 0x20, 0x36, 0xbf, 0x26,
+ 0x2b, 0x4e, 0xc0, 0xd4, 0xbd, 0x22, 0x64, 0xc4, 0x1c, 0x56, 0x69, 0xdb,
+ 0x5f, 0x89, 0xe1, 0x75, 0x68, 0x8d, 0x0e, 0xab, 0x1c, 0x10, 0x1a, 0xc0,
+ 0x12, 0x5d, 0x6f, 0xbd, 0x09, 0xbb, 0x47, 0xcb, 0xe7, 0x34, 0xef, 0x56,
+ 0xab, 0xea, 0xc3, 0xe9, 0x7f, 0x9a, 0x3d, 0xe9, 0x2d, 0x14, 0x61, 0x25,
+ 0x37, 0x5c, 0x3b, 0x4b, 0xaf, 0x5a, 0x4b, 0xc8, 0x99, 0x1a, 0x32, 0x8f,
+ 0x54, 0x07, 0xd3, 0x57, 0x8a, 0x3d, 0x2a, 0xf7, 0x9e, 0x7e, 0x92, 0x2a,
+ 0x50, 0xe9, 0xd8, 0xdb, 0xd6, 0x03, 0xd3, 0x8e, 0x54, 0x32, 0xce, 0x87,
+ 0x93, 0x92, 0xe7, 0x75, 0xe1, 0x6b, 0x78, 0x1a, 0x85, 0xc2, 0x46, 0xa1,
+ 0x31, 0xbb, 0xc7, 0xb9, 0x1d, 0xd1, 0x71, 0xe0, 0xe2, 0x9b, 0x9c, 0x0d,
+ 0xa3, 0xcf, 0x93, 0x4d, 0x87, 0x7b, 0x65, 0xd9, 0xda, 0x4c, 0xd9, 0x6a,
+ 0xa6, 0x36, 0xc2, 0xc7, 0xe3, 0x33, 0xe2, 0xc3, 0x83, 0xd1, 0x72, 0x54,
+ 0x30, 0x81, 0x5e, 0x34, 0x2c, 0x61, 0xee, 0xf4, 0x48, 0x97, 0xb6, 0xaa,
+ 0x47, 0x6a, 0x05, 0x09, 0xd8, 0x4d, 0x90, 0xaf, 0xa8, 0x4e, 0x82, 0xe4,
+ 0x8e, 0xb5, 0xe2, 0x65, 0x86, 0x67, 0xe9, 0x5b, 0x4b, 0x9a, 0x68, 0x08,
+ 0x30, 0xf6, 0x25, 0x8b, 0x20, 0xda, 0x26, 0x6f, 0xbd, 0x0d, 0xa5, 0xd8,
+ 0x6a, 0x7b, 0x01, 0x2f, 0xab, 0x7b, 0xb5, 0xfe, 0x62, 0x37, 0x2d, 0x94,
+ 0x43, 0x2f, 0x4d, 0x16, 0x01, 0x00, 0x01, 0x00,
+};
+
+// 2048 bit RSA signature.
+const uint8_t kSignature2048[ANDROID_PUBKEY_MODULUS_SIZE] = {
+ 0x3a, 0x11, 0x84, 0x40, 0xc1, 0x2f, 0x13, 0x8c, 0xde, 0xb0, 0xc3, 0x89,
+ 0x8a, 0x63, 0xb2, 0x50, 0x93, 0x58, 0xc0, 0x0c, 0xb7, 0x08, 0xe7, 0x6c,
+ 0x52, 0x87, 0x4e, 0x78, 0x89, 0xa3, 0x9a, 0x47, 0xeb, 0x11, 0x57, 0xbc,
+ 0xb3, 0x97, 0xf8, 0x34, 0xf1, 0xf7, 0xbf, 0x3a, 0xfa, 0x1c, 0x6b, 0xdc,
+ 0xd1, 0x02, 0xde, 0x9a, 0x0d, 0x72, 0xe7, 0x19, 0x63, 0x81, 0x46, 0x68,
+ 0x1e, 0x63, 0x64, 0xc6, 0x59, 0xe7, 0x7c, 0x39, 0xed, 0x32, 0xd2, 0xd1,
+ 0xd5, 0x1f, 0x13, 0x9b, 0x52, 0xdf, 0x34, 0xa3, 0xc0, 0xc4, 0x9a, 0x63,
+ 0x9b, 0x9c, 0xbe, 0x22, 0xc8, 0xd8, 0x14, 0x2f, 0x4c, 0x78, 0x36, 0xdb,
+ 0x16, 0x41, 0x67, 0xc1, 0x21, 0x8a, 0x73, 0xb2, 0xe5, 0xb0, 0xd3, 0x80,
+ 0x91, 0x7a, 0xbf, 0xf9, 0x59, 0x4a, 0x4d, 0x78, 0x45, 0x44, 0xa1, 0x52,
+ 0x86, 0x29, 0x48, 0x4d, 0xf0, 0x5d, 0xf2, 0x55, 0xa7, 0xcd, 0xc5, 0x2b,
+ 0x7b, 0xe0, 0xb1, 0xf6, 0x2a, 0xd5, 0x61, 0xba, 0x1e, 0x1e, 0x3a, 0xf0,
+ 0x55, 0xbc, 0x8c, 0x44, 0x41, 0xfc, 0xb8, 0x8c, 0x76, 0xbf, 0x80, 0x58,
+ 0x82, 0x35, 0x4b, 0x0c, 0xfd, 0xef, 0xd5, 0x70, 0xd1, 0x64, 0xcb, 0x46,
+ 0x58, 0x37, 0xbc, 0xa9, 0x7d, 0xd4, 0x70, 0xac, 0xce, 0xec, 0xca, 0x48,
+ 0xcb, 0x0a, 0x40, 0x77, 0x04, 0x59, 0xca, 0x9c, 0x7d, 0x1a, 0x0b, 0xf0,
+ 0xb5, 0xdd, 0xde, 0x71, 0x18, 0xb8, 0xef, 0x90, 0x2a, 0x09, 0x42, 0x39,
+ 0x74, 0xff, 0x45, 0xa1, 0x39, 0x17, 0x50, 0x89, 0xa6, 0x5f, 0xbc, 0x9c,
+ 0x0c, 0x9b, 0x47, 0x25, 0x79, 0x3e, 0xe3, 0xaa, 0xaf, 0xbe, 0x73, 0x6b,
+ 0xcb, 0xe7, 0x35, 0xc1, 0x27, 0x09, 0xcd, 0xeb, 0xd7, 0xcf, 0x63, 0x83,
+ 0x64, 0x8c, 0x45, 0x1c, 0x1d, 0x58, 0xcc, 0xd2, 0xf8, 0x2b, 0x4c, 0x4e,
+ 0x14, 0x89, 0x2d, 0x70,
+};
+
+struct AndroidPubkeyTest : public ::testing::Test {
+ void SetUp() override {
+ RSA* new_key = nullptr;
+ ASSERT_TRUE(android_pubkey_decode(kKey2048, sizeof(kKey2048), &new_key));
+ key_.reset(new_key);
+ }
+
+ std::unique_ptr<RSA, void(*)(RSA*)> key_ = {nullptr, RSA_free};
+};
+
+TEST_F(AndroidPubkeyTest, Decode) {
+ // Make sure the decoded key successfully verifies a valid signature.
+ EXPECT_TRUE(RSA_verify(NID_sha256, kDigest, sizeof(kDigest), kSignature2048,
+ sizeof(kSignature2048), key_.get()));
+}
+
+TEST_F(AndroidPubkeyTest, Encode) {
+ uint8_t key_data[ANDROID_PUBKEY_ENCODED_SIZE];
+ ASSERT_TRUE(android_pubkey_encode(key_.get(), key_data, sizeof(key_data)));
+ ASSERT_EQ(0, memcmp(kKey2048, key_data, sizeof(kKey2048)));
+}
diff --git a/libcutils/qtaguid.c b/libcutils/qtaguid.c
index 2fbe02e..dcd16ef 100644
--- a/libcutils/qtaguid.c
+++ b/libcutils/qtaguid.c
@@ -47,10 +47,7 @@
/* Only call once per process. */
void qtaguid_resTrack(void) {
- resTrackFd = TEMP_FAILURE_RETRY(open("/dev/xt_qtaguid", O_RDONLY));
- if (resTrackFd >=0) {
- TEMP_FAILURE_RETRY(fcntl(resTrackFd, F_SETFD, FD_CLOEXEC));
- }
+ resTrackFd = TEMP_FAILURE_RETRY(open("/dev/xt_qtaguid", O_RDONLY | O_CLOEXEC));
}
/*
@@ -63,7 +60,7 @@
ALOGV("write_ctrl(%s)", cmd);
- fd = TEMP_FAILURE_RETRY(open(CTRL_PROCPATH, O_WRONLY));
+ fd = TEMP_FAILURE_RETRY(open(CTRL_PROCPATH, O_WRONLY | O_CLOEXEC));
if (fd < 0) {
return -errno;
}
@@ -86,7 +83,7 @@
int param_fd;
int res;
- param_fd = TEMP_FAILURE_RETRY(open(param_path, O_WRONLY));
+ param_fd = TEMP_FAILURE_RETRY(open(param_path, O_WRONLY | O_CLOEXEC));
if (param_fd < 0) {
return -errno;
}
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index b399643..884ee17 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -337,7 +337,7 @@
char thread_name[255];
int fd;
- sprintf(statfile, "/proc/%d/stat", tid);
+ snprintf(statfile, sizeof(statfile), "/proc/%d/stat", tid);
memset(thread_name, 0, sizeof(thread_name));
fd = open(statfile, O_RDONLY);
diff --git a/libcutils/tests/PropertiesTest.cpp b/libcutils/tests/PropertiesTest.cpp
index 659821c..5f2396b 100644
--- a/libcutils/tests/PropertiesTest.cpp
+++ b/libcutils/tests/PropertiesTest.cpp
@@ -15,7 +15,7 @@
*/
#define LOG_TAG "Properties_test"
-#include <utils/Log.h>
+#include <cutils/log.h>
#include <gtest/gtest.h>
#include <cutils/properties.h>
@@ -106,14 +106,14 @@
ResetValue();
// Since the value is null, default value will be returned
- int len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);
+ size_t len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);
EXPECT_EQ(strlen(PROPERTY_TEST_VALUE_DEFAULT), len);
EXPECT_STREQ(PROPERTY_TEST_VALUE_DEFAULT, mValue);
}
// Trivial case => get returns what was set
{
- int len = SetAndGetProperty("hello_world");
+ size_t len = SetAndGetProperty("hello_world");
EXPECT_EQ(strlen("hello_world"), len) << "hello_world key";
EXPECT_STREQ("hello_world", mValue);
ResetValue();
@@ -122,7 +122,7 @@
// Set to empty string => get returns default always
{
const char* EMPTY_STRING_DEFAULT = "EMPTY_STRING";
- int len = SetAndGetProperty("", EMPTY_STRING_DEFAULT);
+ size_t len = SetAndGetProperty("", EMPTY_STRING_DEFAULT);
EXPECT_EQ(strlen(EMPTY_STRING_DEFAULT), len) << "empty key";
EXPECT_STREQ(EMPTY_STRING_DEFAULT, mValue);
ResetValue();
@@ -147,7 +147,7 @@
// Expect that the value set fails since it's too long
EXPECT_GT(0, property_set(PROPERTY_TEST_KEY, oneLongerString.c_str()));
- int len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);
+ size_t len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);
EXPECT_EQ(strlen(VALID_TEST_VALUE), len) << "set should've failed";
EXPECT_STREQ(VALID_TEST_VALUE, mValue);
diff --git a/libdiskconfig/Android.mk b/libdiskconfig/Android.mk
index 624e385..a49ce58 100644
--- a/libdiskconfig/Android.mk
+++ b/libdiskconfig/Android.mk
@@ -13,6 +13,8 @@
LOCAL_MODULE_TAGS := optional
LOCAL_SYSTEM_SHARED_LIBRARIES := libcutils liblog libc
LOCAL_CFLAGS := -Werror
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
include $(BUILD_SHARED_LIBRARY)
ifeq ($(HOST_OS),linux)
@@ -21,5 +23,7 @@
LOCAL_MODULE := libdiskconfig_host
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -O2 -g -W -Wall -Werror -D_LARGEFILE64_SOURCE
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
include $(BUILD_HOST_STATIC_LIBRARY)
endif # HOST_OS == linux
diff --git a/include/diskconfig/diskconfig.h b/libdiskconfig/include/diskconfig/diskconfig.h
similarity index 100%
rename from include/diskconfig/diskconfig.h
rename to libdiskconfig/include/diskconfig/diskconfig.h
diff --git a/libion/tests/Android.mk b/libion/tests/Android.mk
index 894f90e..d4d07c2 100644
--- a/libion/tests/Android.mk
+++ b/libion/tests/Android.mk
@@ -17,8 +17,9 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
+LOCAL_CLANG := true
LOCAL_MODULE := ion-unit-tests
-LOCAL_CFLAGS += -g -Wall -Werror -std=gnu++11 -Wno-missing-field-initializers
+LOCAL_CFLAGS += -g -Wall -Werror -Wno-missing-field-initializers
LOCAL_SHARED_LIBRARIES += libion
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../kernel-headers
LOCAL_SRC_FILES := \
diff --git a/libion/tests/allocate_test.cpp b/libion/tests/allocate_test.cpp
index e26b302..3c4524e 100644
--- a/libion/tests/allocate_test.cpp
+++ b/libion/tests/allocate_test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <memory>
#include <sys/mman.h>
#include <gtest/gtest.h>
@@ -90,7 +91,7 @@
TEST_F(Allocate, Zeroed)
{
- void *zeroes = calloc(4096, 1);
+ auto zeroes_ptr = std::make_unique<char[]>(4096);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
@@ -125,14 +126,11 @@
ptr = mmap(NULL, 4096, PROT_READ, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
- ASSERT_EQ(0, memcmp(ptr, zeroes, 4096));
+ ASSERT_EQ(0, memcmp(ptr, zeroes_ptr.get(), 4096));
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
-
- free(zeroes);
-
}
TEST_F(Allocate, Large)
diff --git a/libion/tests/device_test.cpp b/libion/tests/device_test.cpp
index 6f6e1bd..0be52bf 100644
--- a/libion/tests/device_test.cpp
+++ b/libion/tests/device_test.cpp
@@ -15,6 +15,7 @@
*/
#include <fcntl.h>
+#include <memory>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -133,8 +134,8 @@
TEST_F(Device, KernelReadCached)
{
- void *alloc = malloc(8192 + 1024);
- void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
+ auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
+ void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
@@ -161,14 +162,12 @@
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
-
- free(alloc);
}
TEST_F(Device, KernelWriteCached)
{
- void *alloc = malloc(8192 + 1024);
- void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
+ auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
+ void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
for (int i = 0; i < 4096; i++)
((char *)buf)[i] = i;
@@ -195,14 +194,12 @@
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
-
- free(alloc);
}
TEST_F(Device, DMAReadCached)
{
- void *alloc = malloc(8192 + 1024);
- void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
+ auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
+ void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
@@ -227,14 +224,12 @@
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
-
- free(alloc);
}
TEST_F(Device, DMAWriteCached)
{
- void *alloc = malloc(8192 + 1024);
- void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
+ auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
+ void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
for (int i = 0; i < 4096; i++)
((char *)buf)[i] = i;
@@ -261,14 +256,12 @@
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
-
- free(alloc);
}
TEST_F(Device, KernelReadCachedNeedsSync)
{
- void *alloc = malloc(8192 + 1024);
- void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
+ auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
+ void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
@@ -295,14 +288,12 @@
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
-
- free(alloc);
}
TEST_F(Device, KernelWriteCachedNeedsSync)
{
- void *alloc = malloc(8192 + 1024);
- void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
+ auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
+ void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
for (int i = 0; i < 4096; i++)
((char *)buf)[i] = i;
@@ -329,14 +320,12 @@
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
-
- free(alloc);
}
TEST_F(Device, DMAReadCachedNeedsSync)
{
- void *alloc = malloc(8192 + 1024);
- void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
+ auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
+ void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
@@ -363,14 +352,12 @@
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
-
- free(alloc);
}
TEST_F(Device, DMAWriteCachedNeedsSync)
{
- void *alloc = malloc(8192 + 1024);
- void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
+ auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
+ void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
for (int i = 0; i < 4096; i++)
((char *)buf)[i] = i;
@@ -399,13 +386,11 @@
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
-
- free(alloc);
}
TEST_F(Device, KernelRead)
{
- void *alloc = malloc(8192 + 1024);
- void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
+ auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
+ void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
@@ -432,14 +417,12 @@
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
-
- free(alloc);
}
TEST_F(Device, KernelWrite)
{
- void *alloc = malloc(8192 + 1024);
- void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
+ auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
+ void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
for (int i = 0; i < 4096; i++)
((char *)buf)[i] = i;
@@ -466,14 +449,12 @@
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
-
- free(alloc);
}
TEST_F(Device, DMARead)
{
- void *alloc = malloc(8192 + 1024);
- void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
+ auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
+ void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
@@ -498,14 +479,12 @@
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
-
- free(alloc);
}
TEST_F(Device, DMAWrite)
{
- void *alloc = malloc(8192 + 1024);
- void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
+ auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
+ void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
for (int i = 0; i < 4096; i++)
((char *)buf)[i] = i;
@@ -532,13 +511,12 @@
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
-
- free(alloc);
}
TEST_F(Device, IsCached)
{
- void *buf = malloc(4096);
+ auto buf_ptr = std::make_unique<char[]>(4096);
+ void *buf = buf_ptr.get();
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 9c68fca..1051016 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -56,7 +56,9 @@
android: {
srcs: liblog_target_sources,
// AddressSanitizer runtime library depends on liblog.
- sanitize: ["never"],
+ sanitize: {
+ never: true,
+ },
},
android_arm: {
// TODO: This is to work around b/24465209. Remove after root cause is fixed
diff --git a/liblog/logprint.c b/liblog/logprint.c
index 9b60d4a..88afc14 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -21,6 +21,7 @@
#include <assert.h>
#include <ctype.h>
#include <errno.h>
+#include <pwd.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
@@ -28,11 +29,11 @@
#include <string.h>
#include <inttypes.h>
#include <sys/param.h>
+#include <sys/types.h>
#include <cutils/list.h>
#include <log/logd.h>
#include <log/logprint.h>
-#include <private/android_filesystem_config.h>
#include "log_portability.h"
@@ -1352,17 +1353,17 @@
uid[0] = '\0';
if (p_format->uid_output) {
if (entry->uid >= 0) {
- const struct android_id_info *info = android_ids;
- size_t i;
- for (i = 0; i < android_id_count; ++i) {
- if (info->aid == (unsigned int)entry->uid) {
- break;
- }
- ++info;
- }
- if ((i < android_id_count) && (strlen(info->name) <= 5)) {
- snprintf(uid, sizeof(uid), "%5s:", info->name);
+ /*
+ * This code is Android specific, bionic guarantees that
+ * calls to non-reentrant getpwuid() are thread safe.
+ */
+#ifndef __BIONIC__
+#warning "This code assumes that getpwuid is thread safe, only true with Bionic!"
+#endif
+ struct passwd* pwd = getpwuid(entry->uid);
+ if (pwd && (strlen(pwd->pw_name) <= 5)) {
+ snprintf(uid, sizeof(uid), "%5s:", pwd->pw_name);
} else {
// Not worth parsing package list, names all longer than 5
snprintf(uid, sizeof(uid), "%5d:", entry->uid);
diff --git a/liblog/tests/libc_test.cpp b/liblog/tests/libc_test.cpp
index 9dd6f03..3d58147 100644
--- a/liblog/tests/libc_test.cpp
+++ b/liblog/tests/libc_test.cpp
@@ -14,126 +14,9 @@
* limitations under the License.
*/
-#include <fcntl.h>
-#include <sys/cdefs.h>
-
#include <gtest/gtest.h>
-// Should be in bionic test suite, *but* we are using liblog to confirm
-// end-to-end logging, so let the overly cute oedipus complex begin ...
-#include "../../../../bionic/libc/bionic/libc_logging.cpp" // not Standalone
-#define _ANDROID_LOG_H // Priorities redefined
-#define _LIBS_LOG_LOG_H // log ids redefined
-typedef unsigned char log_id_t; // log_id_t missing as a result
-#define _LIBS_LOG_LOG_READ_H // log_time redefined
-
-#include <log/log.h>
-#include <log/logger.h>
-#include <log/log_read.h>
-
-TEST(libc, __libc_android_log_event_int) {
- struct logger_list *logger_list;
-
- pid_t pid = getpid();
-
- ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
- LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
-
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- int value = ts.tv_nsec;
-
- __libc_android_log_event_int(0, value);
- usleep(1000000);
-
- int count = 0;
-
- for (;;) {
- log_msg log_msg;
- if (android_logger_list_read(logger_list, &log_msg) <= 0) {
- break;
- }
-
- ASSERT_EQ(log_msg.entry.pid, pid);
-
- if ((log_msg.entry.len != (4 + 1 + 4))
- || ((int)log_msg.id() != LOG_ID_EVENTS)) {
- continue;
- }
-
- char *eventData = log_msg.msg();
-
- int incoming = (eventData[0] & 0xFF) |
- ((eventData[1] & 0xFF) << 8) |
- ((eventData[2] & 0xFF) << 16) |
- ((eventData[3] & 0xFF) << 24);
-
- if (incoming != 0) {
- continue;
- }
-
- if (eventData[4] != EVENT_TYPE_INT) {
- continue;
- }
-
- incoming = (eventData[4 + 1 + 0] & 0xFF) |
- ((eventData[4 + 1 + 1] & 0xFF) << 8) |
- ((eventData[4 + 1 + 2] & 0xFF) << 16) |
- ((eventData[4 + 1 + 3] & 0xFF) << 24);
-
- if (incoming == value) {
- ++count;
- }
- }
-
- EXPECT_EQ(1, count);
-
- android_logger_list_close(logger_list);
-}
-
-TEST(libc, __libc_fatal_no_abort) {
- struct logger_list *logger_list;
-
- pid_t pid = getpid();
-
- ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
- (log_id_t)LOG_ID_CRASH, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
-
- char b[80];
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
-
- __libc_fatal_no_abort("%u.%09u", (unsigned)ts.tv_sec, (unsigned)ts.tv_nsec);
- snprintf(b, sizeof(b),"%u.%09u", (unsigned)ts.tv_sec, (unsigned)ts.tv_nsec);
- usleep(1000000);
-
- int count = 0;
-
- for (;;) {
- log_msg log_msg;
- if (android_logger_list_read(logger_list, &log_msg) <= 0) {
- break;
- }
-
- ASSERT_EQ(log_msg.entry.pid, pid);
-
- if ((int)log_msg.id() != LOG_ID_CRASH) {
- continue;
- }
-
- char *data = log_msg.msg();
-
- if ((*data == ANDROID_LOG_FATAL)
- && !strcmp(data + 1, "libc")
- && !strcmp(data + 1 + strlen(data + 1) + 1, b)) {
- ++count;
- }
- }
-
- EXPECT_EQ(1, count);
-
- android_logger_list_close(logger_list);
-}
+#include <stdio.h>
TEST(libc, __pstore_append) {
FILE *fp;
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 6aa4fb7..1a7d4aa 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -174,7 +174,7 @@
return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
}
-TEST(liblog, __android_log_bswrite) {
+static void bswrite_test(const char *message) {
struct logger_list *logger_list;
pid_t pid = getpid();
@@ -182,10 +182,30 @@
ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
- static const char buffer[] = "Hello World";
log_time ts(android_log_clockid());
- ASSERT_LT(0, __android_log_bswrite(0, buffer));
+ ASSERT_LT(0, __android_log_bswrite(0, message));
+ size_t num_lines = 1, size = 0, length = 0, total = 0;
+ const char *cp = message;
+ while (*cp) {
+ if (*cp == '\n') {
+ if (cp[1]) {
+ ++num_lines;
+ }
+ } else {
+ ++size;
+ }
+ ++cp;
+ ++total;
+ ++length;
+ if ((LOGGER_ENTRY_MAX_PAYLOAD - 4 - 1 - 4) <= length) {
+ break;
+ }
+ }
+ while (*cp) {
+ ++cp;
+ ++total;
+ }
usleep(1000000);
int count = 0;
@@ -200,7 +220,7 @@
if ((log_msg.entry.sec < (ts.tv_sec - 1))
|| ((ts.tv_sec + 1) < log_msg.entry.sec)
- || (log_msg.entry.len != (4 + 1 + 4 + sizeof(buffer) - 1))
+ || ((size_t)log_msg.entry.len != (4 + 1 + 4 + length))
|| (log_msg.id() != LOG_ID_EVENTS)) {
continue;
}
@@ -211,21 +231,22 @@
continue;
}
- int len = get4LE(eventData + 4 + 1);
- if (len == (sizeof(buffer) - 1)) {
+ size_t len = get4LE(eventData + 4 + 1);
+ if (len == total) {
++count;
AndroidLogFormat *logformat = android_log_format_new();
EXPECT_TRUE(NULL != logformat);
AndroidLogEntry entry;
char msgBuf[1024];
- EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
- &entry,
- NULL,
- msgBuf,
- sizeof(msgBuf)));
- fflush(stderr);
- EXPECT_EQ(31, android_log_printLogLine(logformat, fileno(stderr), &entry));
+ int processBinaryLogBuffer = android_log_processBinaryLogBuffer(
+ &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf));
+ EXPECT_EQ((length == total) ? 0 : -1, processBinaryLogBuffer);
+ if (processBinaryLogBuffer == 0) {
+ fflush(stderr);
+ EXPECT_EQ((int)((20 * num_lines) + size),
+ android_log_printLogLine(logformat, fileno(stderr), &entry));
+ }
android_log_format_free(logformat);
}
}
@@ -235,18 +256,55 @@
android_logger_list_close(logger_list);
}
-TEST(liblog, __android_log_bswrite__empty_string) {
+TEST(liblog, __android_log_bswrite_and_print) {
+ bswrite_test("Hello World");
+}
+
+TEST(liblog, __android_log_bswrite_and_print__empty_string) {
+ bswrite_test("");
+}
+
+TEST(liblog, __android_log_bswrite_and_print__newline_prefix) {
+ bswrite_test("\nHello World\n");
+}
+
+TEST(liblog, __android_log_bswrite_and_print__newline_space_prefix) {
+ bswrite_test("\n Hello World \n");
+}
+
+TEST(liblog, __android_log_bswrite_and_print__multiple_newline) {
+ bswrite_test("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten");
+}
+
+static void buf_write_test(const char *message) {
struct logger_list *logger_list;
pid_t pid = getpid();
ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
- LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
+ LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
- static const char buffer[] = "";
+ static const char tag[] = "TEST__android_log_buf_write";
log_time ts(android_log_clockid());
- ASSERT_LT(0, __android_log_bswrite(0, buffer));
+ EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
+ tag, message));
+ size_t num_lines = 1, size = 0, length = 0;
+ const char *cp = message;
+ while (*cp) {
+ if (*cp == '\n') {
+ if (cp[1]) {
+ ++num_lines;
+ }
+ } else {
+ ++size;
+ }
+ ++length;
+ if ((LOGGER_ENTRY_MAX_PAYLOAD - 2 - sizeof(tag)) <= length) {
+ break;
+ }
+ ++cp;
+ }
usleep(1000000);
int count = 0;
@@ -261,34 +319,25 @@
if ((log_msg.entry.sec < (ts.tv_sec - 1))
|| ((ts.tv_sec + 1) < log_msg.entry.sec)
- || (log_msg.entry.len != (4 + 1 + 4))
- || (log_msg.id() != LOG_ID_EVENTS)) {
+ || ((size_t)log_msg.entry.len != (sizeof(tag) + length + 2))
+ || (log_msg.id() != LOG_ID_MAIN)) {
continue;
}
- char *eventData = log_msg.msg();
+ ++count;
- if (eventData[4] != EVENT_TYPE_STRING) {
- continue;
- }
-
- int len = get4LE(eventData + 4 + 1);
- if (len == 0) {
- ++count;
-
- AndroidLogFormat *logformat = android_log_format_new();
- EXPECT_TRUE(NULL != logformat);
- AndroidLogEntry entry;
- char msgBuf[1024];
- EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
- &entry,
- NULL,
- msgBuf,
- sizeof(msgBuf)));
+ AndroidLogFormat *logformat = android_log_format_new();
+ EXPECT_TRUE(NULL != logformat);
+ AndroidLogEntry entry;
+ int processLogBuffer = android_log_processLogBuffer(&log_msg.entry_v1,
+ &entry);
+ EXPECT_EQ(0, processLogBuffer);
+ if (processLogBuffer == 0) {
fflush(stderr);
- EXPECT_EQ(20, android_log_printLogLine(logformat, fileno(stderr), &entry));
- android_log_format_free(logformat);
+ EXPECT_EQ((int)(((11 + sizeof(tag)) * num_lines) + size),
+ android_log_printLogLine(logformat, fileno(stderr), &entry));
}
+ android_log_format_free(logformat);
}
EXPECT_EQ(1, count);
@@ -296,6 +345,18 @@
android_logger_list_close(logger_list);
}
+TEST(liblog, __android_log_buf_write_and_print__empty) {
+ buf_write_test("");
+}
+
+TEST(liblog, __android_log_buf_write_and_print__newline_prefix) {
+ buf_write_test("\nHello World\n");
+}
+
+TEST(liblog, __android_log_buf_write_and_print__newline_space_prefix) {
+ buf_write_test("\n Hello World \n");
+}
+
TEST(liblog, __security) {
static const char persist_key[] = "persist.logd.security";
static const char readonly_key[] = "ro.device_owner";
@@ -767,7 +828,7 @@
EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
}
-static const char max_payload_tag[] = "TEST_max_payload_XXXX";
+static const char max_payload_tag[] = "TEST_max_payload_and_longish_tag_XXXX";
#define SIZEOF_MAX_PAYLOAD_BUF (LOGGER_ENTRY_MAX_PAYLOAD - \
sizeof(max_payload_tag) - 1)
static const char max_payload_buf[] = "LEONATO\n\
@@ -1802,6 +1863,14 @@
android_logger_list_close(logger_list);
}
+TEST(liblog, __android_log_bswrite_and_print___max) {
+ bswrite_test(max_payload_buf);
+}
+
+TEST(liblog, __android_log_buf_write_and_print__max) {
+ buf_write_test(max_payload_buf);
+}
+
TEST(liblog, android_errorWriteLog__android_logger_list_read__success) {
const int TAG = 123456785;
const char SUBTAG[] = "test-subtag";
diff --git a/libmemtrack/Android.mk b/libmemtrack/Android.mk
index 7b170f5..ffc7244 100644
--- a/libmemtrack/Android.mk
+++ b/libmemtrack/Android.mk
@@ -5,6 +5,8 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := memtrack.c
LOCAL_MODULE := libmemtrack
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_C_INCLUDES += hardware/libhardware/include
LOCAL_SHARED_LIBRARIES := libhardware liblog
LOCAL_CFLAGS := -Wall -Werror
diff --git a/include/memtrack/memtrack.h b/libmemtrack/include/memtrack/memtrack.h
similarity index 98%
rename from include/memtrack/memtrack.h
rename to libmemtrack/include/memtrack/memtrack.h
index 3917300..8c0ab89 100644
--- a/include/memtrack/memtrack.h
+++ b/libmemtrack/include/memtrack/memtrack.h
@@ -19,7 +19,6 @@
#include <sys/types.h>
#include <stddef.h>
-#include <cutils/compiler.h>
#ifdef __cplusplus
extern "C" {
diff --git a/libmemunreachable/ProcessMappings.cpp b/libmemunreachable/ProcessMappings.cpp
index 7cca7c1..57b2321 100644
--- a/libmemunreachable/ProcessMappings.cpp
+++ b/libmemunreachable/ProcessMappings.cpp
@@ -30,11 +30,10 @@
bool ProcessMappings(pid_t pid, allocator::vector<Mapping>& mappings) {
char map_buffer[1024];
snprintf(map_buffer, sizeof(map_buffer), "/proc/%d/maps", pid);
- int fd = open(map_buffer, O_RDONLY);
- if (fd < 0) {
+ android::base::unique_fd fd(open(map_buffer, O_RDONLY));
+ if (fd == -1) {
return false;
}
- android::base::unique_fd fd_guard{fd};
LineBuffer line_buf(fd, map_buffer, sizeof(map_buffer));
char* line;
diff --git a/libmemunreachable/ThreadCapture.cpp b/libmemunreachable/ThreadCapture.cpp
index e8a8392..9155c29 100644
--- a/libmemunreachable/ThreadCapture.cpp
+++ b/libmemunreachable/ThreadCapture.cpp
@@ -108,12 +108,11 @@
strlcat(path, pid_str, sizeof(path));
strlcat(path, "/task", sizeof(path));
- int fd = open(path, O_CLOEXEC | O_DIRECTORY | O_RDONLY);
- if (fd < 0) {
+ android::base::unique_fd fd(open(path, O_CLOEXEC | O_DIRECTORY | O_RDONLY));
+ if (fd == -1) {
ALOGE("failed to open %s: %s", path, strerror(errno));
return false;
}
- android::base::unique_fd fd_guard{fd};
struct linux_dirent64 {
uint64_t d_ino;
@@ -125,7 +124,7 @@
char dirent_buf[4096];
ssize_t nread;
do {
- nread = syscall(SYS_getdents64, fd, dirent_buf, sizeof(dirent_buf));
+ nread = syscall(SYS_getdents64, fd.get(), dirent_buf, sizeof(dirent_buf));
if (nread < 0) {
ALOGE("failed to get directory entries from %s: %s", path, strerror(errno));
return false;
diff --git a/libmemunreachable/tests/ThreadCapture_test.cpp b/libmemunreachable/tests/ThreadCapture_test.cpp
index cefe94e..41ed84e 100644
--- a/libmemunreachable/tests/ThreadCapture_test.cpp
+++ b/libmemunreachable/tests/ThreadCapture_test.cpp
@@ -28,8 +28,6 @@
#include <gtest/gtest.h>
-#include <android-base/unique_fd.h>
-
#include "Allocator.h"
#include "ScopedDisableMalloc.h"
#include "ScopedPipe.h"
diff --git a/libmincrypt/Android.mk b/libmincrypt/Android.mk
deleted file mode 100644
index 7906986..0000000
--- a/libmincrypt/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2008 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libmincrypt
-LOCAL_SRC_FILES := dsa_sig.c p256.c p256_ec.c p256_ecdsa.c rsa.c sha.c sha256.c
-LOCAL_CFLAGS := -Wall -Werror
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libmincrypt
-LOCAL_SRC_FILES := dsa_sig.c p256.c p256_ec.c p256_ecdsa.c rsa.c sha.c sha256.c
-LOCAL_CFLAGS := -Wall -Werror
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-include $(LOCAL_PATH)/tools/Android.mk \
- $(LOCAL_PATH)/test/Android.mk
diff --git a/libmincrypt/NOTICE b/libmincrypt/NOTICE
deleted file mode 100644
index 430d3d6..0000000
--- a/libmincrypt/NOTICE
+++ /dev/null
@@ -1,23 +0,0 @@
- Copyright 2008, The Android Open Source Project
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of Google Inc. nor the names of its contributors may
- be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/libmincrypt/dsa_sig.c b/libmincrypt/dsa_sig.c
deleted file mode 100644
index 101314b..0000000
--- a/libmincrypt/dsa_sig.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Google Inc. nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-
-#include "mincrypt/dsa_sig.h"
-#include "mincrypt/p256.h"
-
-/**
- * Trims off the leading zero bytes and copy it to a buffer aligning it to the end.
- */
-static inline int trim_to_p256_bytes(unsigned char dst[P256_NBYTES], unsigned char *src,
- int src_len) {
- int dst_offset;
- while (*src == '\0' && src_len > 0) {
- src++;
- src_len--;
- }
- if (src_len > P256_NBYTES || src_len < 1) {
- return 0;
- }
- dst_offset = P256_NBYTES - src_len;
- memset(dst, 0, dst_offset);
- memcpy(dst + dst_offset, src, src_len);
- return 1;
-}
-
-/**
- * Unpacks the ASN.1 DSA signature sequence.
- */
-int dsa_sig_unpack(unsigned char* sig, int sig_len, p256_int* r_int, p256_int* s_int) {
- /*
- * Structure is:
- * 0x30 0xNN SEQUENCE + s_length
- * 0x02 0xNN INTEGER + r_length
- * 0xAA 0xBB .. r_length bytes of "r" (offset 4)
- * 0x02 0xNN INTEGER + s_length
- * 0xMM 0xNN .. s_length bytes of "s" (offset 6 + r_len)
- */
- int seq_len;
- unsigned char r_bytes[P256_NBYTES];
- unsigned char s_bytes[P256_NBYTES];
- int r_len;
- int s_len;
-
- memset(r_bytes, 0, sizeof(r_bytes));
- memset(s_bytes, 0, sizeof(s_bytes));
-
- /*
- * Must have at least:
- * 2 bytes sequence header and length
- * 2 bytes R integer header and length
- * 1 byte of R
- * 2 bytes S integer header and length
- * 1 byte of S
- *
- * 8 bytes total
- */
- if (sig_len < 8 || sig[0] != 0x30 || sig[2] != 0x02) {
- return 0;
- }
-
- seq_len = sig[1];
- if ((seq_len <= 0) || (seq_len + 2 != sig_len)) {
- return 0;
- }
-
- r_len = sig[3];
- /*
- * Must have at least:
- * 2 bytes for R header and length
- * 2 bytes S integer header and length
- * 1 byte of S
- */
- if ((r_len < 1) || (r_len > seq_len - 5) || (sig[4 + r_len] != 0x02)) {
- return 0;
- }
- s_len = sig[5 + r_len];
-
- /**
- * Must have:
- * 2 bytes for R header and length
- * r_len bytes for R
- * 2 bytes S integer header and length
- */
- if ((s_len < 1) || (s_len != seq_len - 4 - r_len)) {
- return 0;
- }
-
- /*
- * ASN.1 encoded integers are zero-padded for positive integers. Make sure we have
- * a correctly-sized buffer and that the resulting integer isn't too large.
- */
- if (!trim_to_p256_bytes(r_bytes, &sig[4], r_len)
- || !trim_to_p256_bytes(s_bytes, &sig[6 + r_len], s_len)) {
- return 0;
- }
-
- p256_from_bin(r_bytes, r_int);
- p256_from_bin(s_bytes, s_int);
-
- return 1;
-}
diff --git a/libmincrypt/p256.c b/libmincrypt/p256.c
deleted file mode 100644
index 555a07a..0000000
--- a/libmincrypt/p256.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Google Inc. nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// This is an implementation of the P256 elliptic curve group. It's written to
-// be portable 32-bit, although it's still constant-time.
-//
-// WARNING: Implementing these functions in a constant-time manner is far from
-// obvious. Be careful when touching this code.
-//
-// See http://www.imperialviolet.org/2010/12/04/ecc.html ([1]) for background.
-
-#include <assert.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "mincrypt/p256.h"
-
-const p256_int SECP256r1_n = // curve order
- {{0xfc632551, 0xf3b9cac2, 0xa7179e84, 0xbce6faad, -1, -1, 0, -1}};
-
-const p256_int SECP256r1_p = // curve field size
- {{-1, -1, -1, 0, 0, 0, 1, -1 }};
-
-const p256_int SECP256r1_b = // curve b
- {{0x27d2604b, 0x3bce3c3e, 0xcc53b0f6, 0x651d06b0,
- 0x769886bc, 0xb3ebbd55, 0xaa3a93e7, 0x5ac635d8}};
-
-void p256_init(p256_int* a) {
- memset(a, 0, sizeof(*a));
-}
-
-void p256_clear(p256_int* a) { p256_init(a); }
-
-int p256_get_bit(const p256_int* scalar, int bit) {
- return (P256_DIGIT(scalar, bit / P256_BITSPERDIGIT)
- >> (bit & (P256_BITSPERDIGIT - 1))) & 1;
-}
-
-int p256_is_zero(const p256_int* a) {
- int i, result = 0;
- for (i = 0; i < P256_NDIGITS; ++i) result |= P256_DIGIT(a, i);
- return !result;
-}
-
-// top, c[] += a[] * b
-// Returns new top
-static p256_digit mulAdd(const p256_int* a,
- p256_digit b,
- p256_digit top,
- p256_digit* c) {
- int i;
- p256_ddigit carry = 0;
-
- for (i = 0; i < P256_NDIGITS; ++i) {
- carry += *c;
- carry += (p256_ddigit)P256_DIGIT(a, i) * b;
- *c++ = (p256_digit)carry;
- carry >>= P256_BITSPERDIGIT;
- }
- return top + (p256_digit)carry;
-}
-
-// top, c[] -= top_a, a[]
-static p256_digit subTop(p256_digit top_a,
- const p256_digit* a,
- p256_digit top_c,
- p256_digit* c) {
- int i;
- p256_sddigit borrow = 0;
-
- for (i = 0; i < P256_NDIGITS; ++i) {
- borrow += *c;
- borrow -= *a++;
- *c++ = (p256_digit)borrow;
- borrow >>= P256_BITSPERDIGIT;
- }
- borrow += top_c;
- borrow -= top_a;
- top_c = (p256_digit)borrow;
- assert((borrow >> P256_BITSPERDIGIT) == 0);
- return top_c;
-}
-
-// top, c[] -= MOD[] & mask (0 or -1)
-// returns new top.
-static p256_digit subM(const p256_int* MOD,
- p256_digit top,
- p256_digit* c,
- p256_digit mask) {
- int i;
- p256_sddigit borrow = 0;
- for (i = 0; i < P256_NDIGITS; ++i) {
- borrow += *c;
- borrow -= P256_DIGIT(MOD, i) & mask;
- *c++ = (p256_digit)borrow;
- borrow >>= P256_BITSPERDIGIT;
- }
- return top + (p256_digit)borrow;
-}
-
-// top, c[] += MOD[] & mask (0 or -1)
-// returns new top.
-static p256_digit addM(const p256_int* MOD,
- p256_digit top,
- p256_digit* c,
- p256_digit mask) {
- int i;
- p256_ddigit carry = 0;
- for (i = 0; i < P256_NDIGITS; ++i) {
- carry += *c;
- carry += P256_DIGIT(MOD, i) & mask;
- *c++ = (p256_digit)carry;
- carry >>= P256_BITSPERDIGIT;
- }
- return top + (p256_digit)carry;
-}
-
-// c = a * b mod MOD. c can be a and/or b.
-void p256_modmul(const p256_int* MOD,
- const p256_int* a,
- const p256_digit top_b,
- const p256_int* b,
- p256_int* c) {
- p256_digit tmp[P256_NDIGITS * 2 + 1] = { 0 };
- p256_digit top = 0;
- int i;
-
- // Multiply/add into tmp.
- for (i = 0; i < P256_NDIGITS; ++i) {
- if (i) tmp[i + P256_NDIGITS - 1] = top;
- top = mulAdd(a, P256_DIGIT(b, i), 0, tmp + i);
- }
-
- // Multiply/add top digit
- tmp[i + P256_NDIGITS - 1] = top;
- top = mulAdd(a, top_b, 0, tmp + i);
-
- // Reduce tmp, digit by digit.
- for (; i >= 0; --i) {
- p256_digit reducer[P256_NDIGITS] = { 0 };
- p256_digit top_reducer;
-
- // top can be any value at this point.
- // Guestimate reducer as top * MOD, since msw of MOD is -1.
- top_reducer = mulAdd(MOD, top, 0, reducer);
-
- // Subtract reducer from top | tmp.
- top = subTop(top_reducer, reducer, top, tmp + i);
-
- // top is now either 0 or 1. Make it 0, fixed-timing.
- assert(top <= 1);
-
- top = subM(MOD, top, tmp + i, ~(top - 1));
-
- assert(top == 0);
-
- // We have now reduced the top digit off tmp. Fetch new top digit.
- top = tmp[i + P256_NDIGITS - 1];
- }
-
- // tmp might still be larger than MOD, yet same bit length.
- // Make sure it is less, fixed-timing.
- addM(MOD, 0, tmp, subM(MOD, 0, tmp, -1));
-
- memcpy(c, tmp, P256_NBYTES);
-}
-int p256_is_odd(const p256_int* a) { return P256_DIGIT(a, 0) & 1; }
-int p256_is_even(const p256_int* a) { return !(P256_DIGIT(a, 0) & 1); }
-
-p256_digit p256_shl(const p256_int* a, int n, p256_int* b) {
- int i;
- p256_digit top = P256_DIGIT(a, P256_NDIGITS - 1);
-
- n %= P256_BITSPERDIGIT;
- for (i = P256_NDIGITS - 1; i > 0; --i) {
- p256_digit accu = (P256_DIGIT(a, i) << n);
- accu |= (P256_DIGIT(a, i - 1) >> (P256_BITSPERDIGIT - n));
- P256_DIGIT(b, i) = accu;
- }
- P256_DIGIT(b, i) = (P256_DIGIT(a, i) << n);
-
- top = (p256_digit)((((p256_ddigit)top) << n) >> P256_BITSPERDIGIT);
-
- return top;
-}
-
-void p256_shr(const p256_int* a, int n, p256_int* b) {
- int i;
-
- n %= P256_BITSPERDIGIT;
- for (i = 0; i < P256_NDIGITS - 1; ++i) {
- p256_digit accu = (P256_DIGIT(a, i) >> n);
- accu |= (P256_DIGIT(a, i + 1) << (P256_BITSPERDIGIT - n));
- P256_DIGIT(b, i) = accu;
- }
- P256_DIGIT(b, i) = (P256_DIGIT(a, i) >> n);
-}
-
-static void p256_shr1(const p256_int* a, int highbit, p256_int* b) {
- int i;
-
- for (i = 0; i < P256_NDIGITS - 1; ++i) {
- p256_digit accu = (P256_DIGIT(a, i) >> 1);
- accu |= (P256_DIGIT(a, i + 1) << (P256_BITSPERDIGIT - 1));
- P256_DIGIT(b, i) = accu;
- }
- P256_DIGIT(b, i) = (P256_DIGIT(a, i) >> 1) |
- (highbit << (P256_BITSPERDIGIT - 1));
-}
-
-// Return -1, 0, 1 for a < b, a == b or a > b respectively.
-int p256_cmp(const p256_int* a, const p256_int* b) {
- int i;
- p256_sddigit borrow = 0;
- p256_digit notzero = 0;
-
- for (i = 0; i < P256_NDIGITS; ++i) {
- borrow += (p256_sddigit)P256_DIGIT(a, i) - P256_DIGIT(b, i);
- // Track whether any result digit is ever not zero.
- // Relies on !!(non-zero) evaluating to 1, e.g., !!(-1) evaluating to 1.
- notzero |= !!((p256_digit)borrow);
- borrow >>= P256_BITSPERDIGIT;
- }
- return (int)borrow | notzero;
-}
-
-// c = a - b. Returns borrow: 0 or -1.
-int p256_sub(const p256_int* a, const p256_int* b, p256_int* c) {
- int i;
- p256_sddigit borrow = 0;
-
- for (i = 0; i < P256_NDIGITS; ++i) {
- borrow += (p256_sddigit)P256_DIGIT(a, i) - P256_DIGIT(b, i);
- if (c) P256_DIGIT(c, i) = (p256_digit)borrow;
- borrow >>= P256_BITSPERDIGIT;
- }
- return (int)borrow;
-}
-
-// c = a + b. Returns carry: 0 or 1.
-int p256_add(const p256_int* a, const p256_int* b, p256_int* c) {
- int i;
- p256_ddigit carry = 0;
-
- for (i = 0; i < P256_NDIGITS; ++i) {
- carry += (p256_ddigit)P256_DIGIT(a, i) + P256_DIGIT(b, i);
- if (c) P256_DIGIT(c, i) = (p256_digit)carry;
- carry >>= P256_BITSPERDIGIT;
- }
- return (int)carry;
-}
-
-// b = a + d. Returns carry, 0 or 1.
-int p256_add_d(const p256_int* a, p256_digit d, p256_int* b) {
- int i;
- p256_ddigit carry = d;
-
- for (i = 0; i < P256_NDIGITS; ++i) {
- carry += (p256_ddigit)P256_DIGIT(a, i);
- if (b) P256_DIGIT(b, i) = (p256_digit)carry;
- carry >>= P256_BITSPERDIGIT;
- }
- return (int)carry;
-}
-
-// b = 1/a mod MOD, binary euclid.
-void p256_modinv_vartime(const p256_int* MOD,
- const p256_int* a,
- p256_int* b) {
- p256_int R = P256_ZERO;
- p256_int S = P256_ONE;
- p256_int U = *MOD;
- p256_int V = *a;
-
- for (;;) {
- if (p256_is_even(&U)) {
- p256_shr1(&U, 0, &U);
- if (p256_is_even(&R)) {
- p256_shr1(&R, 0, &R);
- } else {
- // R = (R+MOD)/2
- p256_shr1(&R, p256_add(&R, MOD, &R), &R);
- }
- } else if (p256_is_even(&V)) {
- p256_shr1(&V, 0, &V);
- if (p256_is_even(&S)) {
- p256_shr1(&S, 0, &S);
- } else {
- // S = (S+MOD)/2
- p256_shr1(&S, p256_add(&S, MOD, &S) , &S);
- }
- } else { // U,V both odd.
- if (!p256_sub(&V, &U, NULL)) {
- p256_sub(&V, &U, &V);
- if (p256_sub(&S, &R, &S)) p256_add(&S, MOD, &S);
- if (p256_is_zero(&V)) break; // done.
- } else {
- p256_sub(&U, &V, &U);
- if (p256_sub(&R, &S, &R)) p256_add(&R, MOD, &R);
- }
- }
- }
-
- p256_mod(MOD, &R, b);
-}
-
-void p256_mod(const p256_int* MOD,
- const p256_int* in,
- p256_int* out) {
- if (out != in) *out = *in;
- addM(MOD, 0, P256_DIGITS(out), subM(MOD, 0, P256_DIGITS(out), -1));
-}
-
-// Verify y^2 == x^3 - 3x + b mod p
-// and 0 < x < p and 0 < y < p
-int p256_is_valid_point(const p256_int* x, const p256_int* y) {
- p256_int y2, x3;
-
- if (p256_cmp(&SECP256r1_p, x) <= 0 ||
- p256_cmp(&SECP256r1_p, y) <= 0 ||
- p256_is_zero(x) ||
- p256_is_zero(y)) return 0;
-
- p256_modmul(&SECP256r1_p, y, 0, y, &y2); // y^2
-
- p256_modmul(&SECP256r1_p, x, 0, x, &x3); // x^2
- p256_modmul(&SECP256r1_p, x, 0, &x3, &x3); // x^3
- if (p256_sub(&x3, x, &x3)) p256_add(&x3, &SECP256r1_p, &x3); // x^3 - x
- if (p256_sub(&x3, x, &x3)) p256_add(&x3, &SECP256r1_p, &x3); // x^3 - 2x
- if (p256_sub(&x3, x, &x3)) p256_add(&x3, &SECP256r1_p, &x3); // x^3 - 3x
- if (p256_add(&x3, &SECP256r1_b, &x3)) // x^3 - 3x + b
- p256_sub(&x3, &SECP256r1_p, &x3);
-
- return p256_cmp(&y2, &x3) == 0;
-}
-
-void p256_from_bin(const uint8_t src[P256_NBYTES], p256_int* dst) {
- int i;
- const uint8_t* p = &src[0];
-
- for (i = P256_NDIGITS - 1; i >= 0; --i) {
- P256_DIGIT(dst, i) =
- (p[0] << 24) |
- (p[1] << 16) |
- (p[2] << 8) |
- p[3];
- p += 4;
- }
-}
diff --git a/libmincrypt/p256_ec.c b/libmincrypt/p256_ec.c
deleted file mode 100644
index 90262cc..0000000
--- a/libmincrypt/p256_ec.c
+++ /dev/null
@@ -1,1279 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Google Inc. nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// This is an implementation of the P256 elliptic curve group. It's written to
-// be portable 32-bit, although it's still constant-time.
-//
-// WARNING: Implementing these functions in a constant-time manner is far from
-// obvious. Be careful when touching this code.
-//
-// See http://www.imperialviolet.org/2010/12/04/ecc.html ([1]) for background.
-
-#include <stdint.h>
-#include <stdio.h>
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "mincrypt/p256.h"
-
-typedef uint8_t u8;
-typedef uint32_t u32;
-typedef int32_t s32;
-typedef uint64_t u64;
-
-/* Our field elements are represented as nine 32-bit limbs.
- *
- * The value of an felem (field element) is:
- * x[0] + (x[1] * 2**29) + (x[2] * 2**57) + ... + (x[8] * 2**228)
- *
- * That is, each limb is alternately 29 or 28-bits wide in little-endian
- * order.
- *
- * This means that an felem hits 2**257, rather than 2**256 as we would like. A
- * 28, 29, ... pattern would cause us to hit 2**256, but that causes problems
- * when multiplying as terms end up one bit short of a limb which would require
- * much bit-shifting to correct.
- *
- * Finally, the values stored in an felem are in Montgomery form. So the value
- * |y| is stored as (y*R) mod p, where p is the P-256 prime and R is 2**257.
- */
-typedef u32 limb;
-#define NLIMBS 9
-typedef limb felem[NLIMBS];
-
-static const limb kBottom28Bits = 0xfffffff;
-static const limb kBottom29Bits = 0x1fffffff;
-
-/* kOne is the number 1 as an felem. It's 2**257 mod p split up into 29 and
- * 28-bit words. */
-static const felem kOne = {
- 2, 0, 0, 0xffff800,
- 0x1fffffff, 0xfffffff, 0x1fbfffff, 0x1ffffff,
- 0
-};
-static const felem kZero = {0};
-static const felem kP = {
- 0x1fffffff, 0xfffffff, 0x1fffffff, 0x3ff,
- 0, 0, 0x200000, 0xf000000,
- 0xfffffff
-};
-static const felem k2P = {
- 0x1ffffffe, 0xfffffff, 0x1fffffff, 0x7ff,
- 0, 0, 0x400000, 0xe000000,
- 0x1fffffff
-};
-/* kPrecomputed contains precomputed values to aid the calculation of scalar
- * multiples of the base point, G. It's actually two, equal length, tables
- * concatenated.
- *
- * The first table contains (x,y) felem pairs for 16 multiples of the base
- * point, G.
- *
- * Index | Index (binary) | Value
- * 0 | 0000 | 0G (all zeros, omitted)
- * 1 | 0001 | G
- * 2 | 0010 | 2**64G
- * 3 | 0011 | 2**64G + G
- * 4 | 0100 | 2**128G
- * 5 | 0101 | 2**128G + G
- * 6 | 0110 | 2**128G + 2**64G
- * 7 | 0111 | 2**128G + 2**64G + G
- * 8 | 1000 | 2**192G
- * 9 | 1001 | 2**192G + G
- * 10 | 1010 | 2**192G + 2**64G
- * 11 | 1011 | 2**192G + 2**64G + G
- * 12 | 1100 | 2**192G + 2**128G
- * 13 | 1101 | 2**192G + 2**128G + G
- * 14 | 1110 | 2**192G + 2**128G + 2**64G
- * 15 | 1111 | 2**192G + 2**128G + 2**64G + G
- *
- * The second table follows the same style, but the terms are 2**32G,
- * 2**96G, 2**160G, 2**224G.
- *
- * This is ~2KB of data. */
-static const limb kPrecomputed[NLIMBS * 2 * 15 * 2] = {
- 0x11522878, 0xe730d41, 0xdb60179, 0x4afe2ff, 0x12883add, 0xcaddd88, 0x119e7edc, 0xd4a6eab, 0x3120bee,
- 0x1d2aac15, 0xf25357c, 0x19e45cdd, 0x5c721d0, 0x1992c5a5, 0xa237487, 0x154ba21, 0x14b10bb, 0xae3fe3,
- 0xd41a576, 0x922fc51, 0x234994f, 0x60b60d3, 0x164586ae, 0xce95f18, 0x1fe49073, 0x3fa36cc, 0x5ebcd2c,
- 0xb402f2f, 0x15c70bf, 0x1561925c, 0x5a26704, 0xda91e90, 0xcdc1c7f, 0x1ea12446, 0xe1ade1e, 0xec91f22,
- 0x26f7778, 0x566847e, 0xa0bec9e, 0x234f453, 0x1a31f21a, 0xd85e75c, 0x56c7109, 0xa267a00, 0xb57c050,
- 0x98fb57, 0xaa837cc, 0x60c0792, 0xcfa5e19, 0x61bab9e, 0x589e39b, 0xa324c5, 0x7d6dee7, 0x2976e4b,
- 0x1fc4124a, 0xa8c244b, 0x1ce86762, 0xcd61c7e, 0x1831c8e0, 0x75774e1, 0x1d96a5a9, 0x843a649, 0xc3ab0fa,
- 0x6e2e7d5, 0x7673a2a, 0x178b65e8, 0x4003e9b, 0x1a1f11c2, 0x7816ea, 0xf643e11, 0x58c43df, 0xf423fc2,
- 0x19633ffa, 0x891f2b2, 0x123c231c, 0x46add8c, 0x54700dd, 0x59e2b17, 0x172db40f, 0x83e277d, 0xb0dd609,
- 0xfd1da12, 0x35c6e52, 0x19ede20c, 0xd19e0c0, 0x97d0f40, 0xb015b19, 0x449e3f5, 0xe10c9e, 0x33ab581,
- 0x56a67ab, 0x577734d, 0x1dddc062, 0xc57b10d, 0x149b39d, 0x26a9e7b, 0xc35df9f, 0x48764cd, 0x76dbcca,
- 0xca4b366, 0xe9303ab, 0x1a7480e7, 0x57e9e81, 0x1e13eb50, 0xf466cf3, 0x6f16b20, 0x4ba3173, 0xc168c33,
- 0x15cb5439, 0x6a38e11, 0x73658bd, 0xb29564f, 0x3f6dc5b, 0x53b97e, 0x1322c4c0, 0x65dd7ff, 0x3a1e4f6,
- 0x14e614aa, 0x9246317, 0x1bc83aca, 0xad97eed, 0xd38ce4a, 0xf82b006, 0x341f077, 0xa6add89, 0x4894acd,
- 0x9f162d5, 0xf8410ef, 0x1b266a56, 0xd7f223, 0x3e0cb92, 0xe39b672, 0x6a2901a, 0x69a8556, 0x7e7c0,
- 0x9b7d8d3, 0x309a80, 0x1ad05f7f, 0xc2fb5dd, 0xcbfd41d, 0x9ceb638, 0x1051825c, 0xda0cf5b, 0x812e881,
- 0x6f35669, 0x6a56f2c, 0x1df8d184, 0x345820, 0x1477d477, 0x1645db1, 0xbe80c51, 0xc22be3e, 0xe35e65a,
- 0x1aeb7aa0, 0xc375315, 0xf67bc99, 0x7fdd7b9, 0x191fc1be, 0x61235d, 0x2c184e9, 0x1c5a839, 0x47a1e26,
- 0xb7cb456, 0x93e225d, 0x14f3c6ed, 0xccc1ac9, 0x17fe37f3, 0x4988989, 0x1a90c502, 0x2f32042, 0xa17769b,
- 0xafd8c7c, 0x8191c6e, 0x1dcdb237, 0x16200c0, 0x107b32a1, 0x66c08db, 0x10d06a02, 0x3fc93, 0x5620023,
- 0x16722b27, 0x68b5c59, 0x270fcfc, 0xfad0ecc, 0xe5de1c2, 0xeab466b, 0x2fc513c, 0x407f75c, 0xbaab133,
- 0x9705fe9, 0xb88b8e7, 0x734c993, 0x1e1ff8f, 0x19156970, 0xabd0f00, 0x10469ea7, 0x3293ac0, 0xcdc98aa,
- 0x1d843fd, 0xe14bfe8, 0x15be825f, 0x8b5212, 0xeb3fb67, 0x81cbd29, 0xbc62f16, 0x2b6fcc7, 0xf5a4e29,
- 0x13560b66, 0xc0b6ac2, 0x51ae690, 0xd41e271, 0xf3e9bd4, 0x1d70aab, 0x1029f72, 0x73e1c35, 0xee70fbc,
- 0xad81baf, 0x9ecc49a, 0x86c741e, 0xfe6be30, 0x176752e7, 0x23d416, 0x1f83de85, 0x27de188, 0x66f70b8,
- 0x181cd51f, 0x96b6e4c, 0x188f2335, 0xa5df759, 0x17a77eb6, 0xfeb0e73, 0x154ae914, 0x2f3ec51, 0x3826b59,
- 0xb91f17d, 0x1c72949, 0x1362bf0a, 0xe23fddf, 0xa5614b0, 0xf7d8f, 0x79061, 0x823d9d2, 0x8213f39,
- 0x1128ae0b, 0xd095d05, 0xb85c0c2, 0x1ecb2ef, 0x24ddc84, 0xe35e901, 0x18411a4a, 0xf5ddc3d, 0x3786689,
- 0x52260e8, 0x5ae3564, 0x542b10d, 0x8d93a45, 0x19952aa4, 0x996cc41, 0x1051a729, 0x4be3499, 0x52b23aa,
- 0x109f307e, 0x6f5b6bb, 0x1f84e1e7, 0x77a0cfa, 0x10c4df3f, 0x25a02ea, 0xb048035, 0xe31de66, 0xc6ecaa3,
- 0x28ea335, 0x2886024, 0x1372f020, 0xf55d35, 0x15e4684c, 0xf2a9e17, 0x1a4a7529, 0xcb7beb1, 0xb2a78a1,
- 0x1ab21f1f, 0x6361ccf, 0x6c9179d, 0xb135627, 0x1267b974, 0x4408bad, 0x1cbff658, 0xe3d6511, 0xc7d76f,
- 0x1cc7a69, 0xe7ee31b, 0x54fab4f, 0x2b914f, 0x1ad27a30, 0xcd3579e, 0xc50124c, 0x50daa90, 0xb13f72,
- 0xb06aa75, 0x70f5cc6, 0x1649e5aa, 0x84a5312, 0x329043c, 0x41c4011, 0x13d32411, 0xb04a838, 0xd760d2d,
- 0x1713b532, 0xbaa0c03, 0x84022ab, 0x6bcf5c1, 0x2f45379, 0x18ae070, 0x18c9e11e, 0x20bca9a, 0x66f496b,
- 0x3eef294, 0x67500d2, 0xd7f613c, 0x2dbbeb, 0xb741038, 0xe04133f, 0x1582968d, 0xbe985f7, 0x1acbc1a,
- 0x1a6a939f, 0x33e50f6, 0xd665ed4, 0xb4b7bd6, 0x1e5a3799, 0x6b33847, 0x17fa56ff, 0x65ef930, 0x21dc4a,
- 0x2b37659, 0x450fe17, 0xb357b65, 0xdf5efac, 0x15397bef, 0x9d35a7f, 0x112ac15f, 0x624e62e, 0xa90ae2f,
- 0x107eecd2, 0x1f69bbe, 0x77d6bce, 0x5741394, 0x13c684fc, 0x950c910, 0x725522b, 0xdc78583, 0x40eeabb,
- 0x1fde328a, 0xbd61d96, 0xd28c387, 0x9e77d89, 0x12550c40, 0x759cb7d, 0x367ef34, 0xae2a960, 0x91b8bdc,
- 0x93462a9, 0xf469ef, 0xb2e9aef, 0xd2ca771, 0x54e1f42, 0x7aaa49, 0x6316abb, 0x2413c8e, 0x5425bf9,
- 0x1bed3e3a, 0xf272274, 0x1f5e7326, 0x6416517, 0xea27072, 0x9cedea7, 0x6e7633, 0x7c91952, 0xd806dce,
- 0x8e2a7e1, 0xe421e1a, 0x418c9e1, 0x1dbc890, 0x1b395c36, 0xa1dc175, 0x1dc4ef73, 0x8956f34, 0xe4b5cf2,
- 0x1b0d3a18, 0x3194a36, 0x6c2641f, 0xe44124c, 0xa2f4eaa, 0xa8c25ba, 0xf927ed7, 0x627b614, 0x7371cca,
- 0xba16694, 0x417bc03, 0x7c0a7e3, 0x9c35c19, 0x1168a205, 0x8b6b00d, 0x10e3edc9, 0x9c19bf2, 0x5882229,
- 0x1b2b4162, 0xa5cef1a, 0x1543622b, 0x9bd433e, 0x364e04d, 0x7480792, 0x5c9b5b3, 0xe85ff25, 0x408ef57,
- 0x1814cfa4, 0x121b41b, 0xd248a0f, 0x3b05222, 0x39bb16a, 0xc75966d, 0xa038113, 0xa4a1769, 0x11fbc6c,
- 0x917e50e, 0xeec3da8, 0x169d6eac, 0x10c1699, 0xa416153, 0xf724912, 0x15cd60b7, 0x4acbad9, 0x5efc5fa,
- 0xf150ed7, 0x122b51, 0x1104b40a, 0xcb7f442, 0xfbb28ff, 0x6ac53ca, 0x196142cc, 0x7bf0fa9, 0x957651,
- 0x4e0f215, 0xed439f8, 0x3f46bd5, 0x5ace82f, 0x110916b6, 0x6db078, 0xffd7d57, 0xf2ecaac, 0xca86dec,
- 0x15d6b2da, 0x965ecc9, 0x1c92b4c2, 0x1f3811, 0x1cb080f5, 0x2d8b804, 0x19d1c12d, 0xf20bd46, 0x1951fa7,
- 0xa3656c3, 0x523a425, 0xfcd0692, 0xd44ddc8, 0x131f0f5b, 0xaf80e4a, 0xcd9fc74, 0x99bb618, 0x2db944c,
- 0xa673090, 0x1c210e1, 0x178c8d23, 0x1474383, 0x10b8743d, 0x985a55b, 0x2e74779, 0x576138, 0x9587927,
- 0x133130fa, 0xbe05516, 0x9f4d619, 0xbb62570, 0x99ec591, 0xd9468fe, 0x1d07782d, 0xfc72e0b, 0x701b298,
- 0x1863863b, 0x85954b8, 0x121a0c36, 0x9e7fedf, 0xf64b429, 0x9b9d71e, 0x14e2f5d8, 0xf858d3a, 0x942eea8,
- 0xda5b765, 0x6edafff, 0xa9d18cc, 0xc65e4ba, 0x1c747e86, 0xe4ea915, 0x1981d7a1, 0x8395659, 0x52ed4e2,
- 0x87d43b7, 0x37ab11b, 0x19d292ce, 0xf8d4692, 0x18c3053f, 0x8863e13, 0x4c146c0, 0x6bdf55a, 0x4e4457d,
- 0x16152289, 0xac78ec2, 0x1a59c5a2, 0x2028b97, 0x71c2d01, 0x295851f, 0x404747b, 0x878558d, 0x7d29aa4,
- 0x13d8341f, 0x8daefd7, 0x139c972d, 0x6b7ea75, 0xd4a9dde, 0xff163d8, 0x81d55d7, 0xa5bef68, 0xb7b30d8,
- 0xbe73d6f, 0xaa88141, 0xd976c81, 0x7e7a9cc, 0x18beb771, 0xd773cbd, 0x13f51951, 0x9d0c177, 0x1c49a78,
-};
-
-
-/* Field element operations: */
-
-/* NON_ZERO_TO_ALL_ONES returns:
- * 0xffffffff for 0 < x <= 2**31
- * 0 for x == 0 or x > 2**31.
- *
- * x must be a u32 or an equivalent type such as limb. */
-#define NON_ZERO_TO_ALL_ONES(x) ((((u32)(x) - 1) >> 31) - 1)
-
-/* felem_reduce_carry adds a multiple of p in order to cancel |carry|,
- * which is a term at 2**257.
- *
- * On entry: carry < 2**3, inout[0,2,...] < 2**29, inout[1,3,...] < 2**28.
- * On exit: inout[0,2,..] < 2**30, inout[1,3,...] < 2**29. */
-static void felem_reduce_carry(felem inout, limb carry) {
- const u32 carry_mask = NON_ZERO_TO_ALL_ONES(carry);
-
- inout[0] += carry << 1;
- inout[3] += 0x10000000 & carry_mask;
- /* carry < 2**3 thus (carry << 11) < 2**14 and we added 2**28 in the
- * previous line therefore this doesn't underflow. */
- inout[3] -= carry << 11;
- inout[4] += (0x20000000 - 1) & carry_mask;
- inout[5] += (0x10000000 - 1) & carry_mask;
- inout[6] += (0x20000000 - 1) & carry_mask;
- inout[6] -= carry << 22;
- /* This may underflow if carry is non-zero but, if so, we'll fix it in the
- * next line. */
- inout[7] -= 1 & carry_mask;
- inout[7] += carry << 25;
-}
-
-/* felem_sum sets out = in+in2.
- *
- * On entry, in[i]+in2[i] must not overflow a 32-bit word.
- * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29 */
-static void felem_sum(felem out, const felem in, const felem in2) {
- limb carry = 0;
- unsigned i;
-
- for (i = 0;; i++) {
- out[i] = in[i] + in2[i];
- out[i] += carry;
- carry = out[i] >> 29;
- out[i] &= kBottom29Bits;
-
- i++;
- if (i == NLIMBS)
- break;
-
- out[i] = in[i] + in2[i];
- out[i] += carry;
- carry = out[i] >> 28;
- out[i] &= kBottom28Bits;
- }
-
- felem_reduce_carry(out, carry);
-}
-
-#define two31m3 (((limb)1) << 31) - (((limb)1) << 3)
-#define two30m2 (((limb)1) << 30) - (((limb)1) << 2)
-#define two30p13m2 (((limb)1) << 30) + (((limb)1) << 13) - (((limb)1) << 2)
-#define two31m2 (((limb)1) << 31) - (((limb)1) << 2)
-#define two31p24m2 (((limb)1) << 31) + (((limb)1) << 24) - (((limb)1) << 2)
-#define two30m27m2 (((limb)1) << 30) - (((limb)1) << 27) - (((limb)1) << 2)
-
-/* zero31 is 0 mod p. */
-static const felem zero31 = { two31m3, two30m2, two31m2, two30p13m2, two31m2, two30m2, two31p24m2, two30m27m2, two31m2 };
-
-/* felem_diff sets out = in-in2.
- *
- * On entry: in[0,2,...] < 2**30, in[1,3,...] < 2**29 and
- * in2[0,2,...] < 2**30, in2[1,3,...] < 2**29.
- * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. */
-static void felem_diff(felem out, const felem in, const felem in2) {
- limb carry = 0;
- unsigned i;
-
- for (i = 0;; i++) {
- out[i] = in[i] - in2[i];
- out[i] += zero31[i];
- out[i] += carry;
- carry = out[i] >> 29;
- out[i] &= kBottom29Bits;
-
- i++;
- if (i == NLIMBS)
- break;
-
- out[i] = in[i] - in2[i];
- out[i] += zero31[i];
- out[i] += carry;
- carry = out[i] >> 28;
- out[i] &= kBottom28Bits;
- }
-
- felem_reduce_carry(out, carry);
-}
-
-/* felem_reduce_degree sets out = tmp/R mod p where tmp contains 64-bit words
- * with the same 29,28,... bit positions as an felem.
- *
- * The values in felems are in Montgomery form: x*R mod p where R = 2**257.
- * Since we just multiplied two Montgomery values together, the result is
- * x*y*R*R mod p. We wish to divide by R in order for the result also to be
- * in Montgomery form.
- *
- * On entry: tmp[i] < 2**64
- * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29 */
-static void felem_reduce_degree(felem out, u64 tmp[17]) {
- /* The following table may be helpful when reading this code:
- *
- * Limb number: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10...
- * Width (bits): 29| 28| 29| 28| 29| 28| 29| 28| 29| 28| 29
- * Start bit: 0 | 29| 57| 86|114|143|171|200|228|257|285
- * (odd phase): 0 | 28| 57| 85|114|142|171|199|228|256|285 */
- limb tmp2[18], carry, x, xMask;
- unsigned i;
-
- /* tmp contains 64-bit words with the same 29,28,29-bit positions as an
- * felem. So the top of an element of tmp might overlap with another
- * element two positions down. The following loop eliminates this
- * overlap. */
- tmp2[0] = (limb)(tmp[0] & kBottom29Bits);
-
- /* In the following we use "(limb) tmp[x]" and "(limb) (tmp[x]>>32)" to try
- * and hint to the compiler that it can do a single-word shift by selecting
- * the right register rather than doing a double-word shift and truncating
- * afterwards. */
- tmp2[1] = ((limb) tmp[0]) >> 29;
- tmp2[1] |= (((limb)(tmp[0] >> 32)) << 3) & kBottom28Bits;
- tmp2[1] += ((limb) tmp[1]) & kBottom28Bits;
- carry = tmp2[1] >> 28;
- tmp2[1] &= kBottom28Bits;
-
- for (i = 2; i < 17; i++) {
- tmp2[i] = ((limb)(tmp[i - 2] >> 32)) >> 25;
- tmp2[i] += ((limb)(tmp[i - 1])) >> 28;
- tmp2[i] += (((limb)(tmp[i - 1] >> 32)) << 4) & kBottom29Bits;
- tmp2[i] += ((limb) tmp[i]) & kBottom29Bits;
- tmp2[i] += carry;
- carry = tmp2[i] >> 29;
- tmp2[i] &= kBottom29Bits;
-
- i++;
- if (i == 17)
- break;
- tmp2[i] = ((limb)(tmp[i - 2] >> 32)) >> 25;
- tmp2[i] += ((limb)(tmp[i - 1])) >> 29;
- tmp2[i] += (((limb)(tmp[i - 1] >> 32)) << 3) & kBottom28Bits;
- tmp2[i] += ((limb) tmp[i]) & kBottom28Bits;
- tmp2[i] += carry;
- carry = tmp2[i] >> 28;
- tmp2[i] &= kBottom28Bits;
- }
-
- tmp2[17] = ((limb)(tmp[15] >> 32)) >> 25;
- tmp2[17] += ((limb)(tmp[16])) >> 29;
- tmp2[17] += (((limb)(tmp[16] >> 32)) << 3);
- tmp2[17] += carry;
-
- /* Montgomery elimination of terms.
- *
- * Since R is 2**257, we can divide by R with a bitwise shift if we can
- * ensure that the right-most 257 bits are all zero. We can make that true by
- * adding multiplies of p without affecting the value.
- *
- * So we eliminate limbs from right to left. Since the bottom 29 bits of p
- * are all ones, then by adding tmp2[0]*p to tmp2 we'll make tmp2[0] == 0.
- * We can do that for 8 further limbs and then right shift to eliminate the
- * extra factor of R. */
- for (i = 0;; i += 2) {
- tmp2[i + 1] += tmp2[i] >> 29;
- x = tmp2[i] & kBottom29Bits;
- xMask = NON_ZERO_TO_ALL_ONES(x);
- tmp2[i] = 0;
-
- /* The bounds calculations for this loop are tricky. Each iteration of
- * the loop eliminates two words by adding values to words to their
- * right.
- *
- * The following table contains the amounts added to each word (as an
- * offset from the value of i at the top of the loop). The amounts are
- * accounted for from the first and second half of the loop separately
- * and are written as, for example, 28 to mean a value <2**28.
- *
- * Word: 3 4 5 6 7 8 9 10
- * Added in top half: 28 11 29 21 29 28
- * 28 29
- * 29
- * Added in bottom half: 29 10 28 21 28 28
- * 29
- *
- * The value that is currently offset 7 will be offset 5 for the next
- * iteration and then offset 3 for the iteration after that. Therefore
- * the total value added will be the values added at 7, 5 and 3.
- *
- * The following table accumulates these values. The sums at the bottom
- * are written as, for example, 29+28, to mean a value < 2**29+2**28.
- *
- * Word: 3 4 5 6 7 8 9 10 11 12 13
- * 28 11 10 29 21 29 28 28 28 28 28
- * 29 28 11 28 29 28 29 28 29 28
- * 29 28 21 21 29 21 29 21
- * 10 29 28 21 28 21 28
- * 28 29 28 29 28 29 28
- * 11 10 29 10 29 10
- * 29 28 11 28 11
- * 29 29
- * --------------------------------------------
- * 30+ 31+ 30+ 31+ 30+
- * 28+ 29+ 28+ 29+ 21+
- * 21+ 28+ 21+ 28+ 10
- * 10 21+ 10 21+
- * 11 11
- *
- * So the greatest amount is added to tmp2[10] and tmp2[12]. If
- * tmp2[10/12] has an initial value of <2**29, then the maximum value
- * will be < 2**31 + 2**30 + 2**28 + 2**21 + 2**11, which is < 2**32,
- * as required. */
- tmp2[i + 3] += (x << 10) & kBottom28Bits;
- tmp2[i + 4] += (x >> 18);
-
- tmp2[i + 6] += (x << 21) & kBottom29Bits;
- tmp2[i + 7] += x >> 8;
-
- /* At position 200, which is the starting bit position for word 7, we
- * have a factor of 0xf000000 = 2**28 - 2**24. */
- tmp2[i + 7] += 0x10000000 & xMask;
- /* Word 7 is 28 bits wide, so the 2**28 term exactly hits word 8. */
- tmp2[i + 8] += (x - 1) & xMask;
- tmp2[i + 7] -= (x << 24) & kBottom28Bits;
- tmp2[i + 8] -= x >> 4;
-
- tmp2[i + 8] += 0x20000000 & xMask;
- tmp2[i + 8] -= x;
- tmp2[i + 8] += (x << 28) & kBottom29Bits;
- tmp2[i + 9] += ((x >> 1) - 1) & xMask;
-
- if (i+1 == NLIMBS)
- break;
- tmp2[i + 2] += tmp2[i + 1] >> 28;
- x = tmp2[i + 1] & kBottom28Bits;
- xMask = NON_ZERO_TO_ALL_ONES(x);
- tmp2[i + 1] = 0;
-
- tmp2[i + 4] += (x << 11) & kBottom29Bits;
- tmp2[i + 5] += (x >> 18);
-
- tmp2[i + 7] += (x << 21) & kBottom28Bits;
- tmp2[i + 8] += x >> 7;
-
- /* At position 199, which is the starting bit of the 8th word when
- * dealing with a context starting on an odd word, we have a factor of
- * 0x1e000000 = 2**29 - 2**25. Since we have not updated i, the 8th
- * word from i+1 is i+8. */
- tmp2[i + 8] += 0x20000000 & xMask;
- tmp2[i + 9] += (x - 1) & xMask;
- tmp2[i + 8] -= (x << 25) & kBottom29Bits;
- tmp2[i + 9] -= x >> 4;
-
- tmp2[i + 9] += 0x10000000 & xMask;
- tmp2[i + 9] -= x;
- tmp2[i + 10] += (x - 1) & xMask;
- }
-
- /* We merge the right shift with a carry chain. The words above 2**257 have
- * widths of 28,29,... which we need to correct when copying them down. */
- carry = 0;
- for (i = 0; i < 8; i++) {
- /* The maximum value of tmp2[i + 9] occurs on the first iteration and
- * is < 2**30+2**29+2**28. Adding 2**29 (from tmp2[i + 10]) is
- * therefore safe. */
- out[i] = tmp2[i + 9];
- out[i] += carry;
- out[i] += (tmp2[i + 10] << 28) & kBottom29Bits;
- carry = out[i] >> 29;
- out[i] &= kBottom29Bits;
-
- i++;
- out[i] = tmp2[i + 9] >> 1;
- out[i] += carry;
- carry = out[i] >> 28;
- out[i] &= kBottom28Bits;
- }
-
- out[8] = tmp2[17];
- out[8] += carry;
- carry = out[8] >> 29;
- out[8] &= kBottom29Bits;
-
- felem_reduce_carry(out, carry);
-}
-
-/* felem_square sets out=in*in.
- *
- * On entry: in[0,2,...] < 2**30, in[1,3,...] < 2**29.
- * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. */
-static void felem_square(felem out, const felem in) {
- u64 tmp[17];
-
- tmp[0] = ((u64) in[0]) * in[0];
- tmp[1] = ((u64) in[0]) * (in[1] << 1);
- tmp[2] = ((u64) in[0]) * (in[2] << 1) +
- ((u64) in[1]) * (in[1] << 1);
- tmp[3] = ((u64) in[0]) * (in[3] << 1) +
- ((u64) in[1]) * (in[2] << 1);
- tmp[4] = ((u64) in[0]) * (in[4] << 1) +
- ((u64) in[1]) * (in[3] << 2) + ((u64) in[2]) * in[2];
- tmp[5] = ((u64) in[0]) * (in[5] << 1) + ((u64) in[1]) *
- (in[4] << 1) + ((u64) in[2]) * (in[3] << 1);
- tmp[6] = ((u64) in[0]) * (in[6] << 1) + ((u64) in[1]) *
- (in[5] << 2) + ((u64) in[2]) * (in[4] << 1) +
- ((u64) in[3]) * (in[3] << 1);
- tmp[7] = ((u64) in[0]) * (in[7] << 1) + ((u64) in[1]) *
- (in[6] << 1) + ((u64) in[2]) * (in[5] << 1) +
- ((u64) in[3]) * (in[4] << 1);
- /* tmp[8] has the greatest value of 2**61 + 2**60 + 2**61 + 2**60 + 2**60,
- * which is < 2**64 as required. */
- tmp[8] = ((u64) in[0]) * (in[8] << 1) + ((u64) in[1]) *
- (in[7] << 2) + ((u64) in[2]) * (in[6] << 1) +
- ((u64) in[3]) * (in[5] << 2) + ((u64) in[4]) * in[4];
- tmp[9] = ((u64) in[1]) * (in[8] << 1) + ((u64) in[2]) *
- (in[7] << 1) + ((u64) in[3]) * (in[6] << 1) +
- ((u64) in[4]) * (in[5] << 1);
- tmp[10] = ((u64) in[2]) * (in[8] << 1) + ((u64) in[3]) *
- (in[7] << 2) + ((u64) in[4]) * (in[6] << 1) +
- ((u64) in[5]) * (in[5] << 1);
- tmp[11] = ((u64) in[3]) * (in[8] << 1) + ((u64) in[4]) *
- (in[7] << 1) + ((u64) in[5]) * (in[6] << 1);
- tmp[12] = ((u64) in[4]) * (in[8] << 1) +
- ((u64) in[5]) * (in[7] << 2) + ((u64) in[6]) * in[6];
- tmp[13] = ((u64) in[5]) * (in[8] << 1) +
- ((u64) in[6]) * (in[7] << 1);
- tmp[14] = ((u64) in[6]) * (in[8] << 1) +
- ((u64) in[7]) * (in[7] << 1);
- tmp[15] = ((u64) in[7]) * (in[8] << 1);
- tmp[16] = ((u64) in[8]) * in[8];
-
- felem_reduce_degree(out, tmp);
-}
-
-/* felem_mul sets out=in*in2.
- *
- * On entry: in[0,2,...] < 2**30, in[1,3,...] < 2**29 and
- * in2[0,2,...] < 2**30, in2[1,3,...] < 2**29.
- * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. */
-static void felem_mul(felem out, const felem in, const felem in2) {
- u64 tmp[17];
-
- tmp[0] = ((u64) in[0]) * in2[0];
- tmp[1] = ((u64) in[0]) * (in2[1] << 0) +
- ((u64) in[1]) * (in2[0] << 0);
- tmp[2] = ((u64) in[0]) * (in2[2] << 0) + ((u64) in[1]) *
- (in2[1] << 1) + ((u64) in[2]) * (in2[0] << 0);
- tmp[3] = ((u64) in[0]) * (in2[3] << 0) + ((u64) in[1]) *
- (in2[2] << 0) + ((u64) in[2]) * (in2[1] << 0) +
- ((u64) in[3]) * (in2[0] << 0);
- tmp[4] = ((u64) in[0]) * (in2[4] << 0) + ((u64) in[1]) *
- (in2[3] << 1) + ((u64) in[2]) * (in2[2] << 0) +
- ((u64) in[3]) * (in2[1] << 1) +
- ((u64) in[4]) * (in2[0] << 0);
- tmp[5] = ((u64) in[0]) * (in2[5] << 0) + ((u64) in[1]) *
- (in2[4] << 0) + ((u64) in[2]) * (in2[3] << 0) +
- ((u64) in[3]) * (in2[2] << 0) + ((u64) in[4]) *
- (in2[1] << 0) + ((u64) in[5]) * (in2[0] << 0);
- tmp[6] = ((u64) in[0]) * (in2[6] << 0) + ((u64) in[1]) *
- (in2[5] << 1) + ((u64) in[2]) * (in2[4] << 0) +
- ((u64) in[3]) * (in2[3] << 1) + ((u64) in[4]) *
- (in2[2] << 0) + ((u64) in[5]) * (in2[1] << 1) +
- ((u64) in[6]) * (in2[0] << 0);
- tmp[7] = ((u64) in[0]) * (in2[7] << 0) + ((u64) in[1]) *
- (in2[6] << 0) + ((u64) in[2]) * (in2[5] << 0) +
- ((u64) in[3]) * (in2[4] << 0) + ((u64) in[4]) *
- (in2[3] << 0) + ((u64) in[5]) * (in2[2] << 0) +
- ((u64) in[6]) * (in2[1] << 0) +
- ((u64) in[7]) * (in2[0] << 0);
- /* tmp[8] has the greatest value but doesn't overflow. See logic in
- * felem_square. */
- tmp[8] = ((u64) in[0]) * (in2[8] << 0) + ((u64) in[1]) *
- (in2[7] << 1) + ((u64) in[2]) * (in2[6] << 0) +
- ((u64) in[3]) * (in2[5] << 1) + ((u64) in[4]) *
- (in2[4] << 0) + ((u64) in[5]) * (in2[3] << 1) +
- ((u64) in[6]) * (in2[2] << 0) + ((u64) in[7]) *
- (in2[1] << 1) + ((u64) in[8]) * (in2[0] << 0);
- tmp[9] = ((u64) in[1]) * (in2[8] << 0) + ((u64) in[2]) *
- (in2[7] << 0) + ((u64) in[3]) * (in2[6] << 0) +
- ((u64) in[4]) * (in2[5] << 0) + ((u64) in[5]) *
- (in2[4] << 0) + ((u64) in[6]) * (in2[3] << 0) +
- ((u64) in[7]) * (in2[2] << 0) +
- ((u64) in[8]) * (in2[1] << 0);
- tmp[10] = ((u64) in[2]) * (in2[8] << 0) + ((u64) in[3]) *
- (in2[7] << 1) + ((u64) in[4]) * (in2[6] << 0) +
- ((u64) in[5]) * (in2[5] << 1) + ((u64) in[6]) *
- (in2[4] << 0) + ((u64) in[7]) * (in2[3] << 1) +
- ((u64) in[8]) * (in2[2] << 0);
- tmp[11] = ((u64) in[3]) * (in2[8] << 0) + ((u64) in[4]) *
- (in2[7] << 0) + ((u64) in[5]) * (in2[6] << 0) +
- ((u64) in[6]) * (in2[5] << 0) + ((u64) in[7]) *
- (in2[4] << 0) + ((u64) in[8]) * (in2[3] << 0);
- tmp[12] = ((u64) in[4]) * (in2[8] << 0) + ((u64) in[5]) *
- (in2[7] << 1) + ((u64) in[6]) * (in2[6] << 0) +
- ((u64) in[7]) * (in2[5] << 1) +
- ((u64) in[8]) * (in2[4] << 0);
- tmp[13] = ((u64) in[5]) * (in2[8] << 0) + ((u64) in[6]) *
- (in2[7] << 0) + ((u64) in[7]) * (in2[6] << 0) +
- ((u64) in[8]) * (in2[5] << 0);
- tmp[14] = ((u64) in[6]) * (in2[8] << 0) + ((u64) in[7]) *
- (in2[7] << 1) + ((u64) in[8]) * (in2[6] << 0);
- tmp[15] = ((u64) in[7]) * (in2[8] << 0) +
- ((u64) in[8]) * (in2[7] << 0);
- tmp[16] = ((u64) in[8]) * (in2[8] << 0);
-
- felem_reduce_degree(out, tmp);
-}
-
-static void felem_assign(felem out, const felem in) {
- memcpy(out, in, sizeof(felem));
-}
-
-/* felem_inv calculates |out| = |in|^{-1}
- *
- * Based on Fermat's Little Theorem:
- * a^p = a (mod p)
- * a^{p-1} = 1 (mod p)
- * a^{p-2} = a^{-1} (mod p)
- */
-static void felem_inv(felem out, const felem in) {
- felem ftmp, ftmp2;
- /* each e_I will hold |in|^{2^I - 1} */
- felem e2, e4, e8, e16, e32, e64;
- unsigned i;
-
- felem_square(ftmp, in); /* 2^1 */
- felem_mul(ftmp, in, ftmp); /* 2^2 - 2^0 */
- felem_assign(e2, ftmp);
- felem_square(ftmp, ftmp); /* 2^3 - 2^1 */
- felem_square(ftmp, ftmp); /* 2^4 - 2^2 */
- felem_mul(ftmp, ftmp, e2); /* 2^4 - 2^0 */
- felem_assign(e4, ftmp);
- felem_square(ftmp, ftmp); /* 2^5 - 2^1 */
- felem_square(ftmp, ftmp); /* 2^6 - 2^2 */
- felem_square(ftmp, ftmp); /* 2^7 - 2^3 */
- felem_square(ftmp, ftmp); /* 2^8 - 2^4 */
- felem_mul(ftmp, ftmp, e4); /* 2^8 - 2^0 */
- felem_assign(e8, ftmp);
- for (i = 0; i < 8; i++) {
- felem_square(ftmp, ftmp);
- } /* 2^16 - 2^8 */
- felem_mul(ftmp, ftmp, e8); /* 2^16 - 2^0 */
- felem_assign(e16, ftmp);
- for (i = 0; i < 16; i++) {
- felem_square(ftmp, ftmp);
- } /* 2^32 - 2^16 */
- felem_mul(ftmp, ftmp, e16); /* 2^32 - 2^0 */
- felem_assign(e32, ftmp);
- for (i = 0; i < 32; i++) {
- felem_square(ftmp, ftmp);
- } /* 2^64 - 2^32 */
- felem_assign(e64, ftmp);
- felem_mul(ftmp, ftmp, in); /* 2^64 - 2^32 + 2^0 */
- for (i = 0; i < 192; i++) {
- felem_square(ftmp, ftmp);
- } /* 2^256 - 2^224 + 2^192 */
-
- felem_mul(ftmp2, e64, e32); /* 2^64 - 2^0 */
- for (i = 0; i < 16; i++) {
- felem_square(ftmp2, ftmp2);
- } /* 2^80 - 2^16 */
- felem_mul(ftmp2, ftmp2, e16); /* 2^80 - 2^0 */
- for (i = 0; i < 8; i++) {
- felem_square(ftmp2, ftmp2);
- } /* 2^88 - 2^8 */
- felem_mul(ftmp2, ftmp2, e8); /* 2^88 - 2^0 */
- for (i = 0; i < 4; i++) {
- felem_square(ftmp2, ftmp2);
- } /* 2^92 - 2^4 */
- felem_mul(ftmp2, ftmp2, e4); /* 2^92 - 2^0 */
- felem_square(ftmp2, ftmp2); /* 2^93 - 2^1 */
- felem_square(ftmp2, ftmp2); /* 2^94 - 2^2 */
- felem_mul(ftmp2, ftmp2, e2); /* 2^94 - 2^0 */
- felem_square(ftmp2, ftmp2); /* 2^95 - 2^1 */
- felem_square(ftmp2, ftmp2); /* 2^96 - 2^2 */
- felem_mul(ftmp2, ftmp2, in); /* 2^96 - 3 */
-
- felem_mul(out, ftmp2, ftmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */
-}
-
-/* felem_scalar_3 sets out=3*out.
- *
- * On entry: out[0,2,...] < 2**30, out[1,3,...] < 2**29.
- * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. */
-static void felem_scalar_3(felem out) {
- limb carry = 0;
- unsigned i;
-
- for (i = 0;; i++) {
- out[i] *= 3;
- out[i] += carry;
- carry = out[i] >> 29;
- out[i] &= kBottom29Bits;
-
- i++;
- if (i == NLIMBS)
- break;
-
- out[i] *= 3;
- out[i] += carry;
- carry = out[i] >> 28;
- out[i] &= kBottom28Bits;
- }
-
- felem_reduce_carry(out, carry);
-}
-
-/* felem_scalar_4 sets out=4*out.
- *
- * On entry: out[0,2,...] < 2**30, out[1,3,...] < 2**29.
- * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. */
-static void felem_scalar_4(felem out) {
- limb carry = 0, next_carry;
- unsigned i;
-
- for (i = 0;; i++) {
- next_carry = out[i] >> 27;
- out[i] <<= 2;
- out[i] &= kBottom29Bits;
- out[i] += carry;
- carry = next_carry + (out[i] >> 29);
- out[i] &= kBottom29Bits;
-
- i++;
- if (i == NLIMBS)
- break;
-
- next_carry = out[i] >> 26;
- out[i] <<= 2;
- out[i] &= kBottom28Bits;
- out[i] += carry;
- carry = next_carry + (out[i] >> 28);
- out[i] &= kBottom28Bits;
- }
-
- felem_reduce_carry(out, carry);
-}
-
-/* felem_scalar_8 sets out=8*out.
- *
- * On entry: out[0,2,...] < 2**30, out[1,3,...] < 2**29.
- * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. */
-static void felem_scalar_8(felem out) {
- limb carry = 0, next_carry;
- unsigned i;
-
- for (i = 0;; i++) {
- next_carry = out[i] >> 26;
- out[i] <<= 3;
- out[i] &= kBottom29Bits;
- out[i] += carry;
- carry = next_carry + (out[i] >> 29);
- out[i] &= kBottom29Bits;
-
- i++;
- if (i == NLIMBS)
- break;
-
- next_carry = out[i] >> 25;
- out[i] <<= 3;
- out[i] &= kBottom28Bits;
- out[i] += carry;
- carry = next_carry + (out[i] >> 28);
- out[i] &= kBottom28Bits;
- }
-
- felem_reduce_carry(out, carry);
-}
-
-/* felem_is_zero_vartime returns 1 iff |in| == 0. It takes a variable amount of
- * time depending on the value of |in|. */
-static char felem_is_zero_vartime(const felem in) {
- limb carry;
- int i;
- limb tmp[NLIMBS];
-
- felem_assign(tmp, in);
-
- /* First, reduce tmp to a minimal form. */
- do {
- carry = 0;
- for (i = 0;; i++) {
- tmp[i] += carry;
- carry = tmp[i] >> 29;
- tmp[i] &= kBottom29Bits;
-
- i++;
- if (i == NLIMBS)
- break;
-
- tmp[i] += carry;
- carry = tmp[i] >> 28;
- tmp[i] &= kBottom28Bits;
- }
-
- felem_reduce_carry(tmp, carry);
- } while (carry);
-
- /* tmp < 2**257, so the only possible zero values are 0, p and 2p. */
- return memcmp(tmp, kZero, sizeof(tmp)) == 0 ||
- memcmp(tmp, kP, sizeof(tmp)) == 0 ||
- memcmp(tmp, k2P, sizeof(tmp)) == 0;
-}
-
-
-/* Group operations:
- *
- * Elements of the elliptic curve group are represented in Jacobian
- * coordinates: (x, y, z). An affine point (x', y') is x'=x/z**2, y'=y/z**3 in
- * Jacobian form. */
-
-/* point_double sets {x_out,y_out,z_out} = 2*{x,y,z}.
- *
- * See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l */
-static void point_double(felem x_out, felem y_out, felem z_out, const felem x,
- const felem y, const felem z) {
- felem delta, gamma, alpha, beta, tmp, tmp2;
-
- felem_square(delta, z);
- felem_square(gamma, y);
- felem_mul(beta, x, gamma);
-
- felem_sum(tmp, x, delta);
- felem_diff(tmp2, x, delta);
- felem_mul(alpha, tmp, tmp2);
- felem_scalar_3(alpha);
-
- felem_sum(tmp, y, z);
- felem_square(tmp, tmp);
- felem_diff(tmp, tmp, gamma);
- felem_diff(z_out, tmp, delta);
-
- felem_scalar_4(beta);
- felem_square(x_out, alpha);
- felem_diff(x_out, x_out, beta);
- felem_diff(x_out, x_out, beta);
-
- felem_diff(tmp, beta, x_out);
- felem_mul(tmp, alpha, tmp);
- felem_square(tmp2, gamma);
- felem_scalar_8(tmp2);
- felem_diff(y_out, tmp, tmp2);
-}
-
-/* point_add_mixed sets {x_out,y_out,z_out} = {x1,y1,z1} + {x2,y2,1}.
- * (i.e. the second point is affine.)
- *
- * See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
- *
- * Note that this function does not handle P+P, infinity+P nor P+infinity
- * correctly. */
-static void point_add_mixed(felem x_out, felem y_out, felem z_out,
- const felem x1, const felem y1, const felem z1,
- const felem x2, const felem y2) {
- felem z1z1, z1z1z1, s2, u2, h, i, j, r, rr, v, tmp;
-
- felem_square(z1z1, z1);
- felem_sum(tmp, z1, z1);
-
- felem_mul(u2, x2, z1z1);
- felem_mul(z1z1z1, z1, z1z1);
- felem_mul(s2, y2, z1z1z1);
- felem_diff(h, u2, x1);
- felem_sum(i, h, h);
- felem_square(i, i);
- felem_mul(j, h, i);
- felem_diff(r, s2, y1);
- felem_sum(r, r, r);
- felem_mul(v, x1, i);
-
- felem_mul(z_out, tmp, h);
- felem_square(rr, r);
- felem_diff(x_out, rr, j);
- felem_diff(x_out, x_out, v);
- felem_diff(x_out, x_out, v);
-
- felem_diff(tmp, v, x_out);
- felem_mul(y_out, tmp, r);
- felem_mul(tmp, y1, j);
- felem_diff(y_out, y_out, tmp);
- felem_diff(y_out, y_out, tmp);
-}
-
-/* point_add sets {x_out,y_out,z_out} = {x1,y1,z1} + {x2,y2,z2}.
- *
- * See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
- *
- * Note that this function does not handle P+P, infinity+P nor P+infinity
- * correctly. */
-static void point_add(felem x_out, felem y_out, felem z_out, const felem x1,
- const felem y1, const felem z1, const felem x2,
- const felem y2, const felem z2) {
- felem z1z1, z1z1z1, z2z2, z2z2z2, s1, s2, u1, u2, h, i, j, r, rr, v, tmp;
-
- felem_square(z1z1, z1);
- felem_square(z2z2, z2);
- felem_mul(u1, x1, z2z2);
-
- felem_sum(tmp, z1, z2);
- felem_square(tmp, tmp);
- felem_diff(tmp, tmp, z1z1);
- felem_diff(tmp, tmp, z2z2);
-
- felem_mul(z2z2z2, z2, z2z2);
- felem_mul(s1, y1, z2z2z2);
-
- felem_mul(u2, x2, z1z1);
- felem_mul(z1z1z1, z1, z1z1);
- felem_mul(s2, y2, z1z1z1);
- felem_diff(h, u2, u1);
- felem_sum(i, h, h);
- felem_square(i, i);
- felem_mul(j, h, i);
- felem_diff(r, s2, s1);
- felem_sum(r, r, r);
- felem_mul(v, u1, i);
-
- felem_mul(z_out, tmp, h);
- felem_square(rr, r);
- felem_diff(x_out, rr, j);
- felem_diff(x_out, x_out, v);
- felem_diff(x_out, x_out, v);
-
- felem_diff(tmp, v, x_out);
- felem_mul(y_out, tmp, r);
- felem_mul(tmp, s1, j);
- felem_diff(y_out, y_out, tmp);
- felem_diff(y_out, y_out, tmp);
-}
-
-/* point_add_or_double_vartime sets {x_out,y_out,z_out} = {x1,y1,z1} +
- * {x2,y2,z2}.
- *
- * See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
- *
- * This function handles the case where {x1,y1,z1}={x2,y2,z2}. */
-static void point_add_or_double_vartime(
- felem x_out, felem y_out, felem z_out, const felem x1, const felem y1,
- const felem z1, const felem x2, const felem y2, const felem z2) {
- felem z1z1, z1z1z1, z2z2, z2z2z2, s1, s2, u1, u2, h, i, j, r, rr, v, tmp;
- char x_equal, y_equal;
-
- felem_square(z1z1, z1);
- felem_square(z2z2, z2);
- felem_mul(u1, x1, z2z2);
-
- felem_sum(tmp, z1, z2);
- felem_square(tmp, tmp);
- felem_diff(tmp, tmp, z1z1);
- felem_diff(tmp, tmp, z2z2);
-
- felem_mul(z2z2z2, z2, z2z2);
- felem_mul(s1, y1, z2z2z2);
-
- felem_mul(u2, x2, z1z1);
- felem_mul(z1z1z1, z1, z1z1);
- felem_mul(s2, y2, z1z1z1);
- felem_diff(h, u2, u1);
- x_equal = felem_is_zero_vartime(h);
- felem_sum(i, h, h);
- felem_square(i, i);
- felem_mul(j, h, i);
- felem_diff(r, s2, s1);
- y_equal = felem_is_zero_vartime(r);
- if (x_equal && y_equal) {
- point_double(x_out, y_out, z_out, x1, y1, z1);
- return;
- }
- felem_sum(r, r, r);
- felem_mul(v, u1, i);
-
- felem_mul(z_out, tmp, h);
- felem_square(rr, r);
- felem_diff(x_out, rr, j);
- felem_diff(x_out, x_out, v);
- felem_diff(x_out, x_out, v);
-
- felem_diff(tmp, v, x_out);
- felem_mul(y_out, tmp, r);
- felem_mul(tmp, s1, j);
- felem_diff(y_out, y_out, tmp);
- felem_diff(y_out, y_out, tmp);
-}
-
-/* copy_conditional sets out=in if mask = 0xffffffff in constant time.
- *
- * On entry: mask is either 0 or 0xffffffff. */
-static void copy_conditional(felem out, const felem in, limb mask) {
- int i;
-
- for (i = 0; i < NLIMBS; i++) {
- const limb tmp = mask & (in[i] ^ out[i]);
- out[i] ^= tmp;
- }
-}
-
-/* select_affine_point sets {out_x,out_y} to the index'th entry of table.
- * On entry: index < 16, table[0] must be zero. */
-static void select_affine_point(felem out_x, felem out_y, const limb* table,
- limb index) {
- limb i, j;
-
- memset(out_x, 0, sizeof(felem));
- memset(out_y, 0, sizeof(felem));
-
- for (i = 1; i < 16; i++) {
- limb mask = i ^ index;
- mask |= mask >> 2;
- mask |= mask >> 1;
- mask &= 1;
- mask--;
- for (j = 0; j < NLIMBS; j++, table++) {
- out_x[j] |= *table & mask;
- }
- for (j = 0; j < NLIMBS; j++, table++) {
- out_y[j] |= *table & mask;
- }
- }
-}
-
-/* select_jacobian_point sets {out_x,out_y,out_z} to the index'th entry of
- * table. On entry: index < 16, table[0] must be zero. */
-static void select_jacobian_point(felem out_x, felem out_y, felem out_z,
- const limb* table, limb index) {
- limb i, j;
-
- memset(out_x, 0, sizeof(felem));
- memset(out_y, 0, sizeof(felem));
- memset(out_z, 0, sizeof(felem));
-
- /* The implicit value at index 0 is all zero. We don't need to perform that
- * iteration of the loop because we already set out_* to zero. */
- table += 3 * NLIMBS;
-
- // Hit all entries to obscure cache profiling.
- for (i = 1; i < 16; i++) {
- limb mask = i ^ index;
- mask |= mask >> 2;
- mask |= mask >> 1;
- mask &= 1;
- mask--;
- for (j = 0; j < NLIMBS; j++, table++) {
- out_x[j] |= *table & mask;
- }
- for (j = 0; j < NLIMBS; j++, table++) {
- out_y[j] |= *table & mask;
- }
- for (j = 0; j < NLIMBS; j++, table++) {
- out_z[j] |= *table & mask;
- }
- }
-}
-
-/* scalar_base_mult sets {nx,ny,nz} = scalar*G where scalar is a little-endian
- * number. Note that the value of scalar must be less than the order of the
- * group. */
-static void scalar_base_mult(felem nx, felem ny, felem nz,
- const p256_int* scalar) {
- int i, j;
- limb n_is_infinity_mask = -1, p_is_noninfinite_mask, mask;
- u32 table_offset;
-
- felem px, py;
- felem tx, ty, tz;
-
- memset(nx, 0, sizeof(felem));
- memset(ny, 0, sizeof(felem));
- memset(nz, 0, sizeof(felem));
-
- /* The loop adds bits at positions 0, 64, 128 and 192, followed by
- * positions 32,96,160 and 224 and does this 32 times. */
- for (i = 0; i < 32; i++) {
- if (i) {
- point_double(nx, ny, nz, nx, ny, nz);
- }
- table_offset = 0;
- for (j = 0; j <= 32; j += 32) {
- char bit0 = p256_get_bit(scalar, 31 - i + j);
- char bit1 = p256_get_bit(scalar, 95 - i + j);
- char bit2 = p256_get_bit(scalar, 159 - i + j);
- char bit3 = p256_get_bit(scalar, 223 - i + j);
- limb index = bit0 | (bit1 << 1) | (bit2 << 2) | (bit3 << 3);
-
- select_affine_point(px, py, kPrecomputed + table_offset, index);
- table_offset += 30 * NLIMBS;
-
- /* Since scalar is less than the order of the group, we know that
- * {nx,ny,nz} != {px,py,1}, unless both are zero, which we handle
- * below. */
- point_add_mixed(tx, ty, tz, nx, ny, nz, px, py);
- /* The result of point_add_mixed is incorrect if {nx,ny,nz} is zero
- * (a.k.a. the point at infinity). We handle that situation by
- * copying the point from the table. */
- copy_conditional(nx, px, n_is_infinity_mask);
- copy_conditional(ny, py, n_is_infinity_mask);
- copy_conditional(nz, kOne, n_is_infinity_mask);
-
- /* Equally, the result is also wrong if the point from the table is
- * zero, which happens when the index is zero. We handle that by
- * only copying from {tx,ty,tz} to {nx,ny,nz} if index != 0. */
- p_is_noninfinite_mask = NON_ZERO_TO_ALL_ONES(index);
- mask = p_is_noninfinite_mask & ~n_is_infinity_mask;
- copy_conditional(nx, tx, mask);
- copy_conditional(ny, ty, mask);
- copy_conditional(nz, tz, mask);
- /* If p was not zero, then n is now non-zero. */
- n_is_infinity_mask &= ~p_is_noninfinite_mask;
- }
- }
-}
-
-/* point_to_affine converts a Jacobian point to an affine point. If the input
- * is the point at infinity then it returns (0, 0) in constant time. */
-static void point_to_affine(felem x_out, felem y_out, const felem nx,
- const felem ny, const felem nz) {
- felem z_inv, z_inv_sq;
- felem_inv(z_inv, nz);
- felem_square(z_inv_sq, z_inv);
- felem_mul(x_out, nx, z_inv_sq);
- felem_mul(z_inv, z_inv, z_inv_sq);
- felem_mul(y_out, ny, z_inv);
-}
-
-/* scalar_base_mult sets {nx,ny,nz} = scalar*{x,y}. */
-static void scalar_mult(felem nx, felem ny, felem nz, const felem x,
- const felem y, const p256_int* scalar) {
- int i;
- felem px, py, pz, tx, ty, tz;
- felem precomp[16][3];
- limb n_is_infinity_mask, index, p_is_noninfinite_mask, mask;
-
- /* We precompute 0,1,2,... times {x,y}. */
- memset(precomp, 0, sizeof(felem) * 3);
- memcpy(&precomp[1][0], x, sizeof(felem));
- memcpy(&precomp[1][1], y, sizeof(felem));
- memcpy(&precomp[1][2], kOne, sizeof(felem));
-
- for (i = 2; i < 16; i += 2) {
- point_double(precomp[i][0], precomp[i][1], precomp[i][2],
- precomp[i / 2][0], precomp[i / 2][1], precomp[i / 2][2]);
-
- point_add_mixed(precomp[i + 1][0], precomp[i + 1][1], precomp[i + 1][2],
- precomp[i][0], precomp[i][1], precomp[i][2], x, y);
- }
-
- memset(nx, 0, sizeof(felem));
- memset(ny, 0, sizeof(felem));
- memset(nz, 0, sizeof(felem));
- n_is_infinity_mask = -1;
-
- /* We add in a window of four bits each iteration and do this 64 times. */
- for (i = 0; i < 256; i += 4) {
- if (i) {
- point_double(nx, ny, nz, nx, ny, nz);
- point_double(nx, ny, nz, nx, ny, nz);
- point_double(nx, ny, nz, nx, ny, nz);
- point_double(nx, ny, nz, nx, ny, nz);
- }
-
- index = (p256_get_bit(scalar, 255 - i - 0) << 3) |
- (p256_get_bit(scalar, 255 - i - 1) << 2) |
- (p256_get_bit(scalar, 255 - i - 2) << 1) |
- p256_get_bit(scalar, 255 - i - 3);
-
- /* See the comments in scalar_base_mult about handling infinities. */
- select_jacobian_point(px, py, pz, precomp[0][0], index);
- point_add(tx, ty, tz, nx, ny, nz, px, py, pz);
- copy_conditional(nx, px, n_is_infinity_mask);
- copy_conditional(ny, py, n_is_infinity_mask);
- copy_conditional(nz, pz, n_is_infinity_mask);
-
- p_is_noninfinite_mask = NON_ZERO_TO_ALL_ONES(index);
- mask = p_is_noninfinite_mask & ~n_is_infinity_mask;
-
- copy_conditional(nx, tx, mask);
- copy_conditional(ny, ty, mask);
- copy_conditional(nz, tz, mask);
- n_is_infinity_mask &= ~p_is_noninfinite_mask;
- }
-}
-
-#define kRDigits {2, 0, 0, 0xfffffffe, 0xffffffff, 0xffffffff, 0xfffffffd, 1} // 2^257 mod p256.p
-
-#define kRInvDigits {0x80000000, 1, 0xffffffff, 0, 0x80000001, 0xfffffffe, 1, 0x7fffffff} // 1 / 2^257 mod p256.p
-
-static const p256_int kR = { kRDigits };
-static const p256_int kRInv = { kRInvDigits };
-
-/* to_montgomery sets out = R*in. */
-static void to_montgomery(felem out, const p256_int* in) {
- p256_int in_shifted;
- int i;
-
- p256_init(&in_shifted);
- p256_modmul(&SECP256r1_p, in, 0, &kR, &in_shifted);
-
- for (i = 0; i < NLIMBS; i++) {
- if ((i & 1) == 0) {
- out[i] = P256_DIGIT(&in_shifted, 0) & kBottom29Bits;
- p256_shr(&in_shifted, 29, &in_shifted);
- } else {
- out[i] = P256_DIGIT(&in_shifted, 0) & kBottom28Bits;
- p256_shr(&in_shifted, 28, &in_shifted);
- }
- }
-
- p256_clear(&in_shifted);
-}
-
-/* from_montgomery sets out=in/R. */
-static void from_montgomery(p256_int* out, const felem in) {
- p256_int result, tmp;
- int i, top;
-
- p256_init(&result);
- p256_init(&tmp);
-
- p256_add_d(&tmp, in[NLIMBS - 1], &result);
- for (i = NLIMBS - 2; i >= 0; i--) {
- if ((i & 1) == 0) {
- top = p256_shl(&result, 29, &tmp);
- } else {
- top = p256_shl(&result, 28, &tmp);
- }
- top |= p256_add_d(&tmp, in[i], &result);
- }
-
- p256_modmul(&SECP256r1_p, &kRInv, top, &result, out);
-
- p256_clear(&result);
- p256_clear(&tmp);
-}
-
-/* p256_base_point_mul sets {out_x,out_y} = nG, where n is < the
- * order of the group. */
-void p256_base_point_mul(const p256_int* n, p256_int* out_x, p256_int* out_y) {
- felem x, y, z;
-
- scalar_base_mult(x, y, z, n);
-
- {
- felem x_affine, y_affine;
-
- point_to_affine(x_affine, y_affine, x, y, z);
- from_montgomery(out_x, x_affine);
- from_montgomery(out_y, y_affine);
- }
-}
-
-/* p256_points_mul_vartime sets {out_x,out_y} = n1*G + n2*{in_x,in_y}, where
- * n1 and n2 are < the order of the group.
- *
- * As indicated by the name, this function operates in variable time. This
- * is safe because it's used for signature validation which doesn't deal
- * with secrets. */
-void p256_points_mul_vartime(
- const p256_int* n1, const p256_int* n2, const p256_int* in_x,
- const p256_int* in_y, p256_int* out_x, p256_int* out_y) {
- felem x1, y1, z1, x2, y2, z2, px, py;
-
- /* If both scalars are zero, then the result is the point at infinity. */
- if (p256_is_zero(n1) != 0 && p256_is_zero(n2) != 0) {
- p256_clear(out_x);
- p256_clear(out_y);
- return;
- }
-
- to_montgomery(px, in_x);
- to_montgomery(py, in_y);
- scalar_base_mult(x1, y1, z1, n1);
- scalar_mult(x2, y2, z2, px, py, n2);
-
- if (p256_is_zero(n2) != 0) {
- /* If n2 == 0, then {x2,y2,z2} is zero and the result is just
- * {x1,y1,z1}. */
- } else if (p256_is_zero(n1) != 0) {
- /* If n1 == 0, then {x1,y1,z1} is zero and the result is just
- * {x2,y2,z2}. */
- memcpy(x1, x2, sizeof(x2));
- memcpy(y1, y2, sizeof(y2));
- memcpy(z1, z2, sizeof(z2));
- } else {
- /* This function handles the case where {x1,y1,z1} == {x2,y2,z2}. */
- point_add_or_double_vartime(x1, y1, z1, x1, y1, z1, x2, y2, z2);
- }
-
- point_to_affine(px, py, x1, y1, z1);
- from_montgomery(out_x, px);
- from_montgomery(out_y, py);
-}
diff --git a/libmincrypt/p256_ecdsa.c b/libmincrypt/p256_ecdsa.c
deleted file mode 100644
index f2264b0..0000000
--- a/libmincrypt/p256_ecdsa.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Google Inc. nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-
-#include "mincrypt/p256_ecdsa.h"
-#include "mincrypt/p256.h"
-
-int p256_ecdsa_verify(const p256_int* key_x, const p256_int* key_y,
- const p256_int* message,
- const p256_int* r, const p256_int* s) {
- p256_int u, v;
-
- // Check public key.
- if (!p256_is_valid_point(key_x, key_y)) return 0;
-
- // Check r and s are != 0 % n.
- p256_mod(&SECP256r1_n, r, &u);
- p256_mod(&SECP256r1_n, s, &v);
- if (p256_is_zero(&u) || p256_is_zero(&v)) return 0;
-
- p256_modinv_vartime(&SECP256r1_n, s, &v);
- p256_modmul(&SECP256r1_n, message, 0, &v, &u); // message / s % n
- p256_modmul(&SECP256r1_n, r, 0, &v, &v); // r / s % n
-
- p256_points_mul_vartime(&u, &v,
- key_x, key_y,
- &u, &v);
-
- p256_mod(&SECP256r1_n, &u, &u); // (x coord % p) % n
- return p256_cmp(r, &u) == 0;
-}
-
diff --git a/libmincrypt/rsa.c b/libmincrypt/rsa.c
deleted file mode 100644
index 9061b3a..0000000
--- a/libmincrypt/rsa.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/* rsa.c
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of Google Inc. nor the names of its contributors may
-** be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
-** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "mincrypt/rsa.h"
-#include "mincrypt/sha.h"
-#include "mincrypt/sha256.h"
-
-// a[] -= mod
-static void subM(const RSAPublicKey* key,
- uint32_t* a) {
- int64_t A = 0;
- int i;
- for (i = 0; i < key->len; ++i) {
- A += (uint64_t)a[i] - key->n[i];
- a[i] = (uint32_t)A;
- A >>= 32;
- }
-}
-
-// return a[] >= mod
-static int geM(const RSAPublicKey* key,
- const uint32_t* a) {
- int i;
- for (i = key->len; i;) {
- --i;
- if (a[i] < key->n[i]) return 0;
- if (a[i] > key->n[i]) return 1;
- }
- return 1; // equal
-}
-
-// montgomery c[] += a * b[] / R % mod
-static void montMulAdd(const RSAPublicKey* key,
- uint32_t* c,
- const uint32_t a,
- const uint32_t* b) {
- uint64_t A = (uint64_t)a * b[0] + c[0];
- uint32_t d0 = (uint32_t)A * key->n0inv;
- uint64_t B = (uint64_t)d0 * key->n[0] + (uint32_t)A;
- int i;
-
- for (i = 1; i < key->len; ++i) {
- A = (A >> 32) + (uint64_t)a * b[i] + c[i];
- B = (B >> 32) + (uint64_t)d0 * key->n[i] + (uint32_t)A;
- c[i - 1] = (uint32_t)B;
- }
-
- A = (A >> 32) + (B >> 32);
-
- c[i - 1] = (uint32_t)A;
-
- if (A >> 32) {
- subM(key, c);
- }
-}
-
-// montgomery c[] = a[] * b[] / R % mod
-static void montMul(const RSAPublicKey* key,
- uint32_t* c,
- const uint32_t* a,
- const uint32_t* b) {
- int i;
- for (i = 0; i < key->len; ++i) {
- c[i] = 0;
- }
- for (i = 0; i < key->len; ++i) {
- montMulAdd(key, c, a[i], b);
- }
-}
-
-// In-place public exponentiation.
-// Input and output big-endian byte array in inout.
-static void modpow(const RSAPublicKey* key,
- uint8_t* inout) {
- uint32_t a[RSANUMWORDS];
- uint32_t aR[RSANUMWORDS];
- uint32_t aaR[RSANUMWORDS];
- uint32_t* aaa = 0;
- int i;
-
- // Convert from big endian byte array to little endian word array.
- for (i = 0; i < key->len; ++i) {
- uint32_t tmp =
- (inout[((key->len - 1 - i) * 4) + 0] << 24) |
- (inout[((key->len - 1 - i) * 4) + 1] << 16) |
- (inout[((key->len - 1 - i) * 4) + 2] << 8) |
- (inout[((key->len - 1 - i) * 4) + 3] << 0);
- a[i] = tmp;
- }
-
- if (key->exponent == 65537) {
- aaa = aaR; // Re-use location.
- montMul(key, aR, a, key->rr); // aR = a * RR / R mod M
- for (i = 0; i < 16; i += 2) {
- montMul(key, aaR, aR, aR); // aaR = aR * aR / R mod M
- montMul(key, aR, aaR, aaR); // aR = aaR * aaR / R mod M
- }
- montMul(key, aaa, aR, a); // aaa = aR * a / R mod M
- } else if (key->exponent == 3) {
- aaa = aR; // Re-use location.
- montMul(key, aR, a, key->rr); /* aR = a * RR / R mod M */
- montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */
- montMul(key, aaa, aaR, a); /* aaa = aaR * a / R mod M */
- }
-
- // Make sure aaa < mod; aaa is at most 1x mod too large.
- if (geM(key, aaa)) {
- subM(key, aaa);
- }
-
- // Convert to bigendian byte array
- for (i = key->len - 1; i >= 0; --i) {
- uint32_t tmp = aaa[i];
- *inout++ = tmp >> 24;
- *inout++ = tmp >> 16;
- *inout++ = tmp >> 8;
- *inout++ = tmp >> 0;
- }
-}
-
-// Expected PKCS1.5 signature padding bytes, for a keytool RSA signature.
-// Has the 0-length optional parameter encoded in the ASN1 (as opposed to the
-// other flavor which omits the optional parameter entirely). This code does not
-// accept signatures without the optional parameter.
-
-/*
-static const uint8_t sha_padding[RSANUMBYTES] = {
- 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30,
- 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
- 0x05, 0x00, 0x04, 0x14,
-
- // 20 bytes of hash go here.
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-};
-*/
-
-// SHA-1 of PKCS1.5 signature sha_padding for 2048 bit, as above.
-// At the location of the bytes of the hash all 00 are hashed.
-static const uint8_t kExpectedPadShaRsa2048[SHA_DIGEST_SIZE] = {
- 0xdc, 0xbd, 0xbe, 0x42, 0xd5, 0xf5, 0xa7, 0x2e,
- 0x6e, 0xfc, 0xf5, 0x5d, 0xaf, 0x9d, 0xea, 0x68,
- 0x7c, 0xfb, 0xf1, 0x67
-};
-
-/*
-static const uint8_t sha256_padding[RSANUMBYTES] = {
- 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30,
- 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
- 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20,
-
- // 32 bytes of hash go here.
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-};
-*/
-
-// SHA-256 of PKCS1.5 signature sha256_padding for 2048 bit, as above.
-// At the location of the bytes of the hash all 00 are hashed.
-static const uint8_t kExpectedPadSha256Rsa2048[SHA256_DIGEST_SIZE] = {
- 0xab, 0x28, 0x8d, 0x8a, 0xd7, 0xd9, 0x59, 0x92,
- 0xba, 0xcc, 0xf8, 0x67, 0x20, 0xe1, 0x15, 0x2e,
- 0x39, 0x8d, 0x80, 0x36, 0xd6, 0x6f, 0xf0, 0xfd,
- 0x90, 0xe8, 0x7d, 0x8b, 0xe1, 0x7c, 0x87, 0x59,
-};
-
-// Verify a 2048-bit RSA PKCS1.5 signature against an expected hash.
-// Both e=3 and e=65537 are supported. hash_len may be
-// SHA_DIGEST_SIZE (== 20) to indicate a SHA-1 hash, or
-// SHA256_DIGEST_SIZE (== 32) to indicate a SHA-256 hash. No other
-// values are supported.
-//
-// Returns 1 on successful verification, 0 on failure.
-int RSA_verify(const RSAPublicKey *key,
- const uint8_t *signature,
- const int len,
- const uint8_t *hash,
- const int hash_len) {
- uint8_t buf[RSANUMBYTES];
- int i;
- const uint8_t* padding_hash;
-
- if (key->len != RSANUMWORDS) {
- return 0; // Wrong key passed in.
- }
-
- if (len != sizeof(buf)) {
- return 0; // Wrong input length.
- }
-
- if (hash_len != SHA_DIGEST_SIZE &&
- hash_len != SHA256_DIGEST_SIZE) {
- return 0; // Unsupported hash.
- }
-
- if (key->exponent != 3 && key->exponent != 65537) {
- return 0; // Unsupported exponent.
- }
-
- for (i = 0; i < len; ++i) { // Copy input to local workspace.
- buf[i] = signature[i];
- }
-
- modpow(key, buf); // In-place exponentiation.
-
- // Xor sha portion, so it all becomes 00 iff equal.
- for (i = len - hash_len; i < len; ++i) {
- buf[i] ^= *hash++;
- }
-
- // Hash resulting buf, in-place.
- switch (hash_len) {
- case SHA_DIGEST_SIZE:
- padding_hash = kExpectedPadShaRsa2048;
- SHA_hash(buf, len, buf);
- break;
- case SHA256_DIGEST_SIZE:
- padding_hash = kExpectedPadSha256Rsa2048;
- SHA256_hash(buf, len, buf);
- break;
- default:
- return 0;
- }
-
- // Compare against expected hash value.
- for (i = 0; i < hash_len; ++i) {
- if (buf[i] != padding_hash[i]) {
- return 0;
- }
- }
-
- return 1; // All checked out OK.
-}
diff --git a/libmincrypt/sha.c b/libmincrypt/sha.c
deleted file mode 100644
index 5bef32e..0000000
--- a/libmincrypt/sha.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/* sha.c
-**
-** Copyright 2013, The Android Open Source Project
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of Google Inc. nor the names of its contributors may
-** be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
-** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-// Optimized for minimal code size.
-
-#include "mincrypt/sha.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-
-#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-static void SHA1_Transform(SHA_CTX* ctx) {
- uint32_t W[80];
- uint32_t A, B, C, D, E;
- uint8_t* p = ctx->buf;
- int t;
-
- for(t = 0; t < 16; ++t) {
- uint32_t tmp = *p++ << 24;
- tmp |= *p++ << 16;
- tmp |= *p++ << 8;
- tmp |= *p++;
- W[t] = tmp;
- }
-
- for(; t < 80; t++) {
- W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
- }
-
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
- E = ctx->state[4];
-
- for(t = 0; t < 80; t++) {
- uint32_t tmp = rol(5,A) + E + W[t];
-
- if (t < 20)
- tmp += (D^(B&(C^D))) + 0x5A827999;
- else if ( t < 40)
- tmp += (B^C^D) + 0x6ED9EBA1;
- else if ( t < 60)
- tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
- else
- tmp += (B^C^D) + 0xCA62C1D6;
-
- E = D;
- D = C;
- C = rol(30,B);
- B = A;
- A = tmp;
- }
-
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
- ctx->state[4] += E;
-}
-
-static const HASH_VTAB SHA_VTAB = {
- SHA_init,
- SHA_update,
- SHA_final,
- SHA_hash,
- SHA_DIGEST_SIZE
-};
-
-void SHA_init(SHA_CTX* ctx) {
- ctx->f = &SHA_VTAB;
- ctx->state[0] = 0x67452301;
- ctx->state[1] = 0xEFCDAB89;
- ctx->state[2] = 0x98BADCFE;
- ctx->state[3] = 0x10325476;
- ctx->state[4] = 0xC3D2E1F0;
- ctx->count = 0;
-}
-
-
-void SHA_update(SHA_CTX* ctx, const void* data, int len) {
- int i = (int) (ctx->count & 63);
- const uint8_t* p = (const uint8_t*)data;
-
- ctx->count += len;
-
- while (len--) {
- ctx->buf[i++] = *p++;
- if (i == 64) {
- SHA1_Transform(ctx);
- i = 0;
- }
- }
-}
-
-
-const uint8_t* SHA_final(SHA_CTX* ctx) {
- uint8_t *p = ctx->buf;
- uint64_t cnt = ctx->count * 8;
- int i;
-
- SHA_update(ctx, (uint8_t*)"\x80", 1);
- while ((ctx->count & 63) != 56) {
- SHA_update(ctx, (uint8_t*)"\0", 1);
- }
- for (i = 0; i < 8; ++i) {
- uint8_t tmp = (uint8_t) (cnt >> ((7 - i) * 8));
- SHA_update(ctx, &tmp, 1);
- }
-
- for (i = 0; i < 5; i++) {
- uint32_t tmp = ctx->state[i];
- *p++ = tmp >> 24;
- *p++ = tmp >> 16;
- *p++ = tmp >> 8;
- *p++ = tmp >> 0;
- }
-
- return ctx->buf;
-}
-
-/* Convenience function */
-const uint8_t* SHA_hash(const void* data, int len, uint8_t* digest) {
- SHA_CTX ctx;
- SHA_init(&ctx);
- SHA_update(&ctx, data, len);
- memcpy(digest, SHA_final(&ctx), SHA_DIGEST_SIZE);
- return digest;
-}
diff --git a/libmincrypt/sha256.c b/libmincrypt/sha256.c
deleted file mode 100644
index eb6e308..0000000
--- a/libmincrypt/sha256.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* sha256.c
-**
-** Copyright 2013, The Android Open Source Project
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of Google Inc. nor the names of its contributors may
-** be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
-** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-// Optimized for minimal code size.
-
-#include "mincrypt/sha256.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-
-#define ror(value, bits) (((value) >> (bits)) | ((value) << (32 - (bits))))
-#define shr(value, bits) ((value) >> (bits))
-
-static const uint32_t K[64] = {
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
- 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
- 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
- 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
- 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
- 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };
-
-static void SHA256_Transform(SHA256_CTX* ctx) {
- uint32_t W[64];
- uint32_t A, B, C, D, E, F, G, H;
- uint8_t* p = ctx->buf;
- int t;
-
- for(t = 0; t < 16; ++t) {
- uint32_t tmp = *p++ << 24;
- tmp |= *p++ << 16;
- tmp |= *p++ << 8;
- tmp |= *p++;
- W[t] = tmp;
- }
-
- for(; t < 64; t++) {
- uint32_t s0 = ror(W[t-15], 7) ^ ror(W[t-15], 18) ^ shr(W[t-15], 3);
- uint32_t s1 = ror(W[t-2], 17) ^ ror(W[t-2], 19) ^ shr(W[t-2], 10);
- W[t] = W[t-16] + s0 + W[t-7] + s1;
- }
-
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
- E = ctx->state[4];
- F = ctx->state[5];
- G = ctx->state[6];
- H = ctx->state[7];
-
- for(t = 0; t < 64; t++) {
- uint32_t s0 = ror(A, 2) ^ ror(A, 13) ^ ror(A, 22);
- uint32_t maj = (A & B) ^ (A & C) ^ (B & C);
- uint32_t t2 = s0 + maj;
- uint32_t s1 = ror(E, 6) ^ ror(E, 11) ^ ror(E, 25);
- uint32_t ch = (E & F) ^ ((~E) & G);
- uint32_t t1 = H + s1 + ch + K[t] + W[t];
-
- H = G;
- G = F;
- F = E;
- E = D + t1;
- D = C;
- C = B;
- B = A;
- A = t1 + t2;
- }
-
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
- ctx->state[4] += E;
- ctx->state[5] += F;
- ctx->state[6] += G;
- ctx->state[7] += H;
-}
-
-static const HASH_VTAB SHA256_VTAB = {
- SHA256_init,
- SHA256_update,
- SHA256_final,
- SHA256_hash,
- SHA256_DIGEST_SIZE
-};
-
-void SHA256_init(SHA256_CTX* ctx) {
- ctx->f = &SHA256_VTAB;
- ctx->state[0] = 0x6a09e667;
- ctx->state[1] = 0xbb67ae85;
- ctx->state[2] = 0x3c6ef372;
- ctx->state[3] = 0xa54ff53a;
- ctx->state[4] = 0x510e527f;
- ctx->state[5] = 0x9b05688c;
- ctx->state[6] = 0x1f83d9ab;
- ctx->state[7] = 0x5be0cd19;
- ctx->count = 0;
-}
-
-
-void SHA256_update(SHA256_CTX* ctx, const void* data, int len) {
- int i = (int) (ctx->count & 63);
- const uint8_t* p = (const uint8_t*)data;
-
- ctx->count += len;
-
- while (len--) {
- ctx->buf[i++] = *p++;
- if (i == 64) {
- SHA256_Transform(ctx);
- i = 0;
- }
- }
-}
-
-
-const uint8_t* SHA256_final(SHA256_CTX* ctx) {
- uint8_t *p = ctx->buf;
- uint64_t cnt = ctx->count * 8;
- int i;
-
- SHA256_update(ctx, (uint8_t*)"\x80", 1);
- while ((ctx->count & 63) != 56) {
- SHA256_update(ctx, (uint8_t*)"\0", 1);
- }
- for (i = 0; i < 8; ++i) {
- uint8_t tmp = (uint8_t) (cnt >> ((7 - i) * 8));
- SHA256_update(ctx, &tmp, 1);
- }
-
- for (i = 0; i < 8; i++) {
- uint32_t tmp = ctx->state[i];
- *p++ = tmp >> 24;
- *p++ = tmp >> 16;
- *p++ = tmp >> 8;
- *p++ = tmp >> 0;
- }
-
- return ctx->buf;
-}
-
-/* Convenience function */
-const uint8_t* SHA256_hash(const void* data, int len, uint8_t* digest) {
- SHA256_CTX ctx;
- SHA256_init(&ctx);
- SHA256_update(&ctx, data, len);
- memcpy(digest, SHA256_final(&ctx), SHA256_DIGEST_SIZE);
- return digest;
-}
diff --git a/libmincrypt/test/Android.mk b/libmincrypt/test/Android.mk
deleted file mode 100644
index 73ff7d0..0000000
--- a/libmincrypt/test/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2013 The Android Open Source Project
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := rsa_test
-LOCAL_SRC_FILES := rsa_test.c
-LOCAL_STATIC_LIBRARIES := libmincrypt
-include $(BUILD_HOST_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := ecdsa_test
-LOCAL_SRC_FILES := ecdsa_test.c
-LOCAL_STATIC_LIBRARIES := libmincrypt
-include $(BUILD_HOST_NATIVE_TEST)
diff --git a/libmincrypt/test/ecdsa_test.c b/libmincrypt/test/ecdsa_test.c
deleted file mode 100644
index 24ec013..0000000
--- a/libmincrypt/test/ecdsa_test.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Google Inc. nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/cdefs.h>
-
-#include "mincrypt/dsa_sig.h"
-#include "mincrypt/p256.h"
-#include "mincrypt/p256_ecdsa.h"
-#include "mincrypt/sha256.h"
-
-#ifndef __unused
-#define __unused __attribute__((__unused__))
-#endif
-
-/**
- * Messages signed using:
- *
------BEGIN EC PRIVATE KEY-----
-MHcCAQEEIDw6UiziVMbjlfSpOAIpA2tcL+v1OlznZLnpadO8BGi1oAoGCCqGSM49
-AwEHoUQDQgAEZw7VAOjAXYRFuhZWYBgjahdOvkwcAnjGkxQWytZW+iS1hI3ZGE24
-6XmNka9IGxAgj2n/ip+MuZJMFoJ9DRea3g==
------END EC PRIVATE KEY-----
- */
-
-p256_int key_x = {
- .a = {0xd656fa24u, 0x931416cau, 0x1c0278c6u, 0x174ebe4cu,
- 0x6018236au, 0x45ba1656u, 0xe8c05d84u, 0x670ed500u}
-};
-p256_int key_y = {
- .a = {0x0d179adeu, 0x4c16827du, 0x9f8cb992u, 0x8f69ff8au,
- 0x481b1020u, 0x798d91afu, 0x184db8e9u, 0xb5848dd9u}
-};
-
-char* message_1 =
- "f4 5d 55 f3 55 51 e9 75 d6 a8 dc 7e a9 f4 88 59"
- "39 40 cc 75 69 4a 27 8f 27 e5 78 a1 63 d8 39 b3"
- "40 40 84 18 08 cf 9c 58 c9 b8 72 8b f5 f9 ce 8e"
- "e8 11 ea 91 71 4f 47 ba b9 2d 0f 6d 5a 26 fc fe"
- "ea 6c d9 3b 91 0c 0a 2c 96 3e 64 eb 18 23 f1 02"
- "75 3d 41 f0 33 59 10 ad 3a 97 71 04 f1 aa f6 c3"
- "74 27 16 a9 75 5d 11 b8 ee d6 90 47 7f 44 5c 5d"
- "27 20 8b 2e 28 43 30 fa 3d 30 14 23 fa 7f 2d 08"
- "6e 0a d0 b8 92 b9 db 54 4e 45 6d 3f 0d ab 85 d9"
- "53 c1 2d 34 0a a8 73 ed a7 27 c8 a6 49 db 7f a6"
- "37 40 e2 5e 9a f1 53 3b 30 7e 61 32 99 93 11 0e"
- "95 19 4e 03 93 99 c3 82 4d 24 c5 1f 22 b2 6b de"
- "10 24 cd 39 59 58 a2 df eb 48 16 a6 e8 ad ed b5"
- "0b 1f 6b 56 d0 b3 06 0f f0 f1 c4 cb 0d 0e 00 1d"
- "d5 9d 73 be 12";
-
-char* signature_1 =
- "30 44 02 20 43 18 fc eb 3b a8 3a a8 a3 cf 41 b7"
- "81 4a f9 01 e1 8b 6e 95 c1 3a 83 25 9e a5 2e 66"
- "7c 98 25 d9 02 20 54 f3 7f 5a e9 36 9c a2 f0 51"
- "e0 6e 78 48 60 a3 f9 8a d5 2c 37 5a 0a 29 c9 f7"
- "ea 57 7e 88 46 12";
-
-// Same as signature 1, but with leading zeroes.
-char* message_2 =
- "f4 5d 55 f3 55 51 e9 75 d6 a8 dc 7e a9 f4 88 59"
- "39 40 cc 75 69 4a 27 8f 27 e5 78 a1 63 d8 39 b3"
- "40 40 84 18 08 cf 9c 58 c9 b8 72 8b f5 f9 ce 8e"
- "e8 11 ea 91 71 4f 47 ba b9 2d 0f 6d 5a 26 fc fe"
- "ea 6c d9 3b 91 0c 0a 2c 96 3e 64 eb 18 23 f1 02"
- "75 3d 41 f0 33 59 10 ad 3a 97 71 04 f1 aa f6 c3"
- "74 27 16 a9 75 5d 11 b8 ee d6 90 47 7f 44 5c 5d"
- "27 20 8b 2e 28 43 30 fa 3d 30 14 23 fa 7f 2d 08"
- "6e 0a d0 b8 92 b9 db 54 4e 45 6d 3f 0d ab 85 d9"
- "53 c1 2d 34 0a a8 73 ed a7 27 c8 a6 49 db 7f a6"
- "37 40 e2 5e 9a f1 53 3b 30 7e 61 32 99 93 11 0e"
- "95 19 4e 03 93 99 c3 82 4d 24 c5 1f 22 b2 6b de"
- "10 24 cd 39 59 58 a2 df eb 48 16 a6 e8 ad ed b5"
- "0b 1f 6b 56 d0 b3 06 0f f0 f1 c4 cb 0d 0e 00 1d"
- "d5 9d 73 be 12";
-
-char* signature_2 =
- "30 46 02 21 00 43 18 fc eb 3b a8 3a a8 a3 cf 41 b7"
- "81 4a f9 01 e1 8b 6e 95 c1 3a 83 25 9e a5 2e 66"
- "7c 98 25 d9 02 21 00 54 f3 7f 5a e9 36 9c a2 f0 51"
- "e0 6e 78 48 60 a3 f9 8a d5 2c 37 5a 0a 29 c9 f7"
- "ea 57 7e 88 46 12";
-
-// Excessive zeroes on the signature
-char* message_3 =
- "f4 5d 55 f3 55 51 e9 75 d6 a8 dc 7e a9 f4 88 59"
- "39 40 cc 75 69 4a 27 8f 27 e5 78 a1 63 d8 39 b3"
- "40 40 84 18 08 cf 9c 58 c9 b8 72 8b f5 f9 ce 8e"
- "e8 11 ea 91 71 4f 47 ba b9 2d 0f 6d 5a 26 fc fe"
- "ea 6c d9 3b 91 0c 0a 2c 96 3e 64 eb 18 23 f1 02"
- "75 3d 41 f0 33 59 10 ad 3a 97 71 04 f1 aa f6 c3"
- "74 27 16 a9 75 5d 11 b8 ee d6 90 47 7f 44 5c 5d"
- "27 20 8b 2e 28 43 30 fa 3d 30 14 23 fa 7f 2d 08"
- "6e 0a d0 b8 92 b9 db 54 4e 45 6d 3f 0d ab 85 d9"
- "53 c1 2d 34 0a a8 73 ed a7 27 c8 a6 49 db 7f a6"
- "37 40 e2 5e 9a f1 53 3b 30 7e 61 32 99 93 11 0e"
- "95 19 4e 03 93 99 c3 82 4d 24 c5 1f 22 b2 6b de"
- "10 24 cd 39 59 58 a2 df eb 48 16 a6 e8 ad ed b5"
- "0b 1f 6b 56 d0 b3 06 0f f0 f1 c4 cb 0d 0e 00 1d"
- "d5 9d 73 be 12";
-
-char* signature_3 =
- "30 4c 02 24 00 00 00 00 43 18 fc eb 3b a8 3a a8 a3 cf 41 b7"
- "81 4a f9 01 e1 8b 6e 95 c1 3a 83 25 9e a5 2e 66"
- "7c 98 25 d9 02 24 00 00 00 00 54 f3 7f 5a e9 36 9c a2 f0 51"
- "e0 6e 78 48 60 a3 f9 8a d5 2c 37 5a 0a 29 c9 f7"
- "ea 57 7e 88 46 12";
-
-
-char* good_dsa_signature_1 =
- "30 0D 02 01 01 02 08 00 A5 55 5A 01 FF A5 01";
-p256_int good_dsa_signature_1_r = {
- .a = {0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U,
- 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U}
-};
-p256_int good_dsa_signature_1_s = {
- .a = {0x01FFA501U, 0x00A5555AU, 0x00000000U, 0x00000000U,
- 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U}
-};
-
-
-char* bad_dsa_signature_1 =
- "a0 06 02 01 01 02 01 01";
-
-char* bad_dsa_signature_2 =
- "30 07 02 01 01 02 01 01";
-
-char* bad_dsa_signature_3 =
- "30 06 82 01 01 02 01 01";
-
-char* bad_dsa_signature_4 =
- "30 06 02 00 01 02 01 01";
-
-char* bad_dsa_signature_5 =
- "30 06 02 01 01 82 01 01";
-
-char* bad_dsa_signature_6 =
- "30 05 02 01 01 02 00";
-
-char* bad_dsa_signature_7 =
- "30 06 02 01 01 02 00 01";
-
-unsigned char* parsehex(char* str, int* len) {
- // result can't be longer than input
- unsigned char* result = malloc(strlen(str));
-
- unsigned char* p = result;
- *len = 0;
-
- while (*str) {
- int b;
-
- while (isspace(*str)) str++;
-
- switch (*str) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- b = (*str - '0') << 4; break;
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- b = (*str - 'a' + 10) << 4; break;
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- b = (*str - 'A' + 10) << 4; break;
- case '\0':
- return result;
- default:
- return NULL;
- }
- str++;
-
- while (isspace(*str)) str++;
-
- switch (*str) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- b |= *str - '0'; break;
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- b |= *str - 'a' + 10; break;
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- b |= *str - 'A' + 10; break;
- default:
- return NULL;
- }
- str++;
-
- *p++ = b;
- ++*len;
- }
-
- return result;
-}
-
-int main(int arg __unused, char** argv __unused) {
-
- unsigned char hash_buf[SHA256_DIGEST_SIZE];
-
- unsigned char* message;
- int mlen;
- unsigned char* signature;
- int slen;
-
- p256_int hash;
- p256_int r;
- p256_int s;
-
- int success = 1;
-
-#define CHECK_DSA_SIG(sig, good) do {\
- message = parsehex(sig, &mlen); \
- int result = dsa_sig_unpack(message, mlen, &r, &s); \
- printf(#sig ": %s\n", result ? "good" : "bad"); \
- success = success && !(good ^ result); \
- free(message); \
- } while(0)
-#define CHECK_GOOD_DSA_SIG(n) do {\
- CHECK_DSA_SIG(good_dsa_signature_##n, 1); \
- int result = !memcmp(P256_DIGITS(&good_dsa_signature_##n##_r), P256_DIGITS(&r), \
- P256_NBYTES); \
- success = success && result; \
- printf(" R value %s\n", result ? "good" : "bad"); \
- result = !memcmp(P256_DIGITS(&good_dsa_signature_##n##_s), P256_DIGITS(&s), \
- P256_NBYTES); \
- success = success && result; \
- printf(" S value %s\n", result ? "good" : "bad"); \
- } while (0)
-#define CHECK_BAD_DSA_SIG(n) \
- CHECK_DSA_SIG(bad_dsa_signature_##n, 0)
-
- CHECK_GOOD_DSA_SIG(1);
-
- CHECK_BAD_DSA_SIG(1);
- CHECK_BAD_DSA_SIG(2);
- CHECK_BAD_DSA_SIG(3);
- CHECK_BAD_DSA_SIG(4);
- CHECK_BAD_DSA_SIG(5);
- CHECK_BAD_DSA_SIG(6);
- CHECK_BAD_DSA_SIG(7);
-
-
-#define TEST_MESSAGE(n) do {\
- message = parsehex(message_##n, &mlen); \
- SHA256_hash(message, mlen, hash_buf); \
- p256_from_bin(hash_buf, &hash); \
- signature = parsehex(signature_##n, &slen); \
- int result = dsa_sig_unpack(signature, slen, &r, &s); \
- if (result) { result = p256_ecdsa_verify(&key_x, &key_y, &hash, &r, &s); } \
- printf("message %d: %s\n", n, result ? "verified" : "not verified"); \
- success = success && result; \
- free(signature); \
- } while(0)
-
- TEST_MESSAGE(1);
- TEST_MESSAGE(2);
- TEST_MESSAGE(3);
-
- printf("\n%s\n\n", success ? "PASS" : "FAIL");
-
- return !success;
-}
diff --git a/libmincrypt/test/rsa_test.c b/libmincrypt/test/rsa_test.c
deleted file mode 100644
index 055138f..0000000
--- a/libmincrypt/test/rsa_test.c
+++ /dev/null
@@ -1,842 +0,0 @@
-/*
-** Copyright 2013, The Android Open Source Project
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of Google Inc. nor the names of its contributors may
-** be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
-** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/cdefs.h>
-
-#include "mincrypt/rsa.h"
-#include "mincrypt/sha.h"
-
-#ifndef __unused
-#define __unused __attribute__((unused))
-#endif
-
-// RSA test data taken from:
-//
-// ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt
-
-// This is the result (reformatted) of running DumpPublicKey on:
-//
-// # Example 15: A 2048-bit RSA key pair
-// # -----------------------------------
-//
-//
-// # Public key
-// # ----------
-//
-// # Modulus:
-// df 27 1f d2 5f 86 44 49 6b 0c 81 be 4b d5 02 97
-// ef 09 9b 00 2a 6f d6 77 27 eb 44 9c ea 56 6e d6
-// a3 98 1a 71 31 2a 14 1c ab c9 81 5c 12 09 e3 20
-// a2 5b 32 46 4e 99 99 f1 8c a1 3a 9f d3 89 25 58
-// f9 e0 ad ef dd 36 50 dd 23 a3 f0 36 d6 0f e3 98
-// 84 37 06 a4 0b 0b 84 62 c8 be e3 bc e1 2f 1f 28
-// 60 c2 44 4c dc 6a 44 47 6a 75 ff 4a a2 42 73 cc
-// be 3b f8 02 48 46 5f 8f f8 c3 a7 f3 36 7d fc 0d
-// f5 b6 50 9a 4f 82 81 1c ed d8 1c da aa 73 c4 91
-// da 41 21 70 d5 44 d4 ba 96 b9 7f 0a fc 80 65 49
-// 8d 3a 49 fd 91 09 92 a1 f0 72 5b e2 4f 46 5c fe
-// 7e 0e ab f6 78 99 6c 50 bc 5e 75 24 ab f7 3f 15
-// e5 be f7 d5 18 39 4e 31 38 ce 49 44 50 6a aa af
-// 3f 9b 23 6d ca b8 fc 00 f8 7a f5 96 fd c3 d9 d6
-// c7 5c d5 08 36 2f ae 2c be dd cc 4c 74 50 b1 7b
-// 77 6c 07 9e cc a1 f2 56 35 1a 43 b9 7d be 21 53
-//
-// # Exponent:
-// 01 00 01
-
-RSAPublicKey key_15 = {
- .len = 64,
- .n0inv = 0xf0053525,
- .n = {2109612371u,890913721u,3433165398u,2003568542u,
- 1951445371u,3202206796u,909094444u,3344749832u,
- 4257470934u,4168807830u,3401120768u,1067131757u,
- 1349167791u,953043268u,406408753u,3854497749u,
- 2885107477u,3160306980u,2023320656u,2114890742u,
- 1330011390u,4034026466u,2433323681u,2369407485u,
- 4236272969u,2528739082u,3578057914u,3661701488u,
- 2859713681u,3990363354u,1333952796u,4122366106u,
- 914226189u,4173572083u,1212571535u,3191601154u,
- 2722264012u,1786117962u,3697951815u,1623344204u,
- 3777961768u,3367953340u,185304162u,2218198692u,
- 3591365528u,597946422u,3711324381u,4192251375u,
- 3548980568u,2359376543u,1318689265u,2723885638u,
- 302637856u,2882109788u,824841244u,2744654449u,
- 3931533014u,669729948u,711972471u,4010384128u,
- 1272251031u,1795981758u,1602634825u,3743883218u},
- .rr = {820482522u,2494434288u,1082168230u,731376296u,
- 1306039452u,3139792975u,2575869288u,3874938710u,
- 3198185181u,153506080u,1236489694u,1061859740u,
- 1174461268u,115279508u,1782749185u,238124145u,
- 3587596076u,2259236093u,1112265915u,4048059865u,
- 3890381098u,999426242u,794481771u,3804065613u,
- 2786019148u,461403875u,3072256692u,4079652654u,
- 3056719901u,1871565394u,212974856u,3359008174u,
- 1397773937u,3796256698u,914342841u,1097174457u,
- 3322220191u,3170814748u,2439215020u,618719336u,
- 3629353460u,496817177u,317052742u,380264245u,
- 1976007217u,2697736152u,312540864u,4291855337u,
- 697006561u,4234182488u,3904590917u,2609582216u,
- 451424084u,1805773827u,776344974u,1064489733u,
- 2633377036u,1954826648u,3202815814u,2240368662u,
- 2618582484u,2211196815u,4107362845u,3640258615u},
- .exponent = 65537,
-};
-
-// PKCS#1 v1.5 Signature Example 15.1
-
-char* message_1 =
- "f4 5d 55 f3 55 51 e9 75 d6 a8 dc 7e a9 f4 88 59"
- "39 40 cc 75 69 4a 27 8f 27 e5 78 a1 63 d8 39 b3"
- "40 40 84 18 08 cf 9c 58 c9 b8 72 8b f5 f9 ce 8e"
- "e8 11 ea 91 71 4f 47 ba b9 2d 0f 6d 5a 26 fc fe"
- "ea 6c d9 3b 91 0c 0a 2c 96 3e 64 eb 18 23 f1 02"
- "75 3d 41 f0 33 59 10 ad 3a 97 71 04 f1 aa f6 c3"
- "74 27 16 a9 75 5d 11 b8 ee d6 90 47 7f 44 5c 5d"
- "27 20 8b 2e 28 43 30 fa 3d 30 14 23 fa 7f 2d 08"
- "6e 0a d0 b8 92 b9 db 54 4e 45 6d 3f 0d ab 85 d9"
- "53 c1 2d 34 0a a8 73 ed a7 27 c8 a6 49 db 7f a6"
- "37 40 e2 5e 9a f1 53 3b 30 7e 61 32 99 93 11 0e"
- "95 19 4e 03 93 99 c3 82 4d 24 c5 1f 22 b2 6b de"
- "10 24 cd 39 59 58 a2 df eb 48 16 a6 e8 ad ed b5"
- "0b 1f 6b 56 d0 b3 06 0f f0 f1 c4 cb 0d 0e 00 1d"
- "d5 9d 73 be 12";
-
-char* signature_1 =
- "b7 5a 54 66 b6 5d 0f 30 0e f5 38 33 f2 17 5c 8a"
- "34 7a 38 04 fc 63 45 1d c9 02 f0 b7 1f 90 83 45"
- "9e d3 7a 51 79 a3 b7 23 a5 3f 10 51 64 2d 77 37"
- "4c 4c 6c 8d bb 1c a2 05 25 f5 c9 f3 2d b7 76 95"
- "35 56 da 31 29 0e 22 19 74 82 ce b6 99 06 c4 6a"
- "75 8f b0 e7 40 9b a8 01 07 7d 2a 0a 20 ea e7 d1"
- "d6 d3 92 ab 49 57 e8 6b 76 f0 65 2d 68 b8 39 88"
- "a7 8f 26 e1 11 72 ea 60 9b f8 49 fb bd 78 ad 7e"
- "dc e2 1d e6 62 a0 81 36 8c 04 06 07 ce e2 9d b0"
- "62 72 27 f4 49 63 ad 17 1d 22 93 b6 33 a3 92 e3"
- "31 dc a5 4f e3 08 27 52 f4 3f 63 c1 61 b4 47 a4"
- "c6 5a 68 75 67 0d 5f 66 00 fc c8 60 a1 ca eb 0a"
- "88 f8 fd ec 4e 56 43 98 a5 c4 6c 87 f6 8c e0 70"
- "01 f6 21 3a be 0a b5 62 5f 87 d1 90 25 f0 8d 81"
- "da c7 bd 45 86 bc 93 82 19 1f 6d 28 80 f6 22 7e"
- "5d f3 ee d2 1e 77 92 d2 49 48 04 87 f3 65 52 61";
-
-// PKCS#1 v1.5 Signature Example 15.2
-
-char *message_2 =
- "c1 4b 4c 60 75 b2 f9 aa d6 61 de f4 ec fd 3c b9 "
- "33 c6 23 f4 e6 3b f5 34 10 d2 f0 16 d1 ab 98 e2 "
- "72 9e cc f8 00 6c d8 e0 80 50 73 7d 95 fd bf 29 "
- "6b 66 f5 b9 79 2a 90 29 36 c4 f7 ac 69 f5 14 53 "
- "ce 43 69 45 2d c2 2d 96 f0 37 74 81 14 66 20 00 "
- "dd 9c d3 a5 e1 79 f4 e0 f8 1f a6 a0 31 1c a1 ae "
- "e6 51 9a 0f 63 ce c7 8d 27 bb 72 63 93 fb 7f 1f "
- "88 cd e7 c9 7f 8a 66 cd 66 30 12 81 da c3 f3 a4 "
- "33 24 8c 75 d6 c2 dc d7 08 b6 a9 7b 0a 3f 32 5e "
- "0b 29 64 f8 a5 81 9e 47 9b ";
-
-char* signature_2 =
- "af a7 34 34 62 be a1 22 cc 14 9f ca 70 ab da e7"
- "94 46 67 7d b5 37 36 66 af 7d c3 13 01 5f 4d e7"
- "86 e6 e3 94 94 6f ad 3c c0 e2 b0 2b ed ba 50 47"
- "fe 9e 2d 7d 09 97 05 e4 a3 9f 28 68 32 79 cf 0a"
- "c8 5c 15 30 41 22 42 c0 e9 18 95 3b e0 00 e9 39"
- "cf 3b f1 82 52 5e 19 93 70 fa 79 07 eb a6 9d 5d"
- "b4 63 10 17 c0 e3 6d f7 03 79 b5 db 8d 4c 69 5a"
- "97 9a 8e 61 73 22 40 65 d7 dc 15 13 2e f2 8c d8"
- "22 79 51 63 06 3b 54 c6 51 14 1b e8 6d 36 e3 67"
- "35 bc 61 f3 1f ca 57 4e 53 09 f3 a3 bb df 91 ef"
- "f1 2b 99 e9 cc 17 44 f1 ee 9a 1b d2 2c 5b ad 96"
- "ad 48 19 29 25 1f 03 43 fd 36 bc f0 ac de 7f 11"
- "e5 ad 60 97 77 21 20 27 96 fe 06 1f 9a da 1f c4"
- "c8 e0 0d 60 22 a8 35 75 85 ff e9 fd d5 93 31 a2"
- "8c 4a a3 12 15 88 fb 6c f6 83 96 d8 ac 05 46 59"
- "95 00 c9 70 85 00 a5 97 2b d5 4f 72 cf 8d b0 c8";
-
-// PKCS#1 v1.5 Signature Example 15.3
-
-char* message_3 =
- "d0 23 71 ad 7e e4 8b bf db 27 63 de 7a 84 3b 94 "
- "08 ce 5e b5 ab f8 47 ca 3d 73 59 86 df 84 e9 06 "
- "0b db cd d3 a5 5b a5 5d de 20 d4 76 1e 1a 21 d2 "
- "25 c1 a1 86 f4 ac 4b 30 19 d3 ad f7 8f e6 33 46 "
- "67 f5 6f 70 c9 01 a0 a2 70 0c 6f 0d 56 ad d7 19 "
- "59 2d c8 8f 6d 23 06 c7 00 9f 6e 7a 63 5b 4c b3 "
- "a5 02 df e6 8d dc 58 d0 3b e1 0a 11 70 00 4f e7 "
- "4d d3 e4 6b 82 59 1f f7 54 14 f0 c4 a0 3e 60 5e "
- "20 52 4f 24 16 f1 2e ca 58 9f 11 1b 75 d6 39 c6 "
- "1b aa 80 ca fd 05 cf 35 00 24 4a 21 9e d9 ce d9 "
- "f0 b1 02 97 18 2b 65 3b 52 6f 40 0f 29 53 ba 21 "
- "4d 5b cd 47 88 41 32 87 2a e9 0d 4d 6b 1f 42 15 "
- "39 f9 f3 46 62 a5 6d c0 e7 b4 b9 23 b6 23 1e 30 "
- "d2 67 67 97 81 7f 7c 33 7b 5a c8 24 ba 93 14 3b "
- "33 81 fa 3d ce 0e 6a eb d3 8e 67 73 51 87 b1 eb "
- "d9 5c 02 ";
-
-char* signature_3 =
- "3b ac 63 f8 6e 3b 70 27 12 03 10 6b 9c 79 aa bd"
- "9f 47 7c 56 e4 ee 58 a4 fc e5 ba f2 ca b4 96 0f"
- "88 39 1c 9c 23 69 8b e7 5c 99 ae df 9e 1a bf 17"
- "05 be 1d ac 33 14 0a db 48 eb 31 f4 50 bb 9e fe"
- "83 b7 b9 0d b7 f1 57 6d 33 f4 0c 1c ba 4b 8d 6b"
- "1d 33 23 56 4b 0f 17 74 11 4f a7 c0 8e 6d 1e 20"
- "dd 8f bb a9 b6 ac 7a d4 1e 26 b4 56 8f 4a 8a ac"
- "bf d1 78 a8 f8 d2 c9 d5 f5 b8 81 12 93 5a 8b c9"
- "ae 32 cd a4 0b 8d 20 37 55 10 73 50 96 53 68 18"
- "ce 2b 2d b7 1a 97 72 c9 b0 dd a0 9a e1 01 52 fa"
- "11 46 62 18 d0 91 b5 3d 92 54 30 61 b7 29 4a 55"
- "be 82 ff 35 d5 c3 2f a2 33 f0 5a aa c7 58 50 30"
- "7e cf 81 38 3c 11 16 74 39 7b 1a 1b 9d 3b f7 61"
- "2c cb e5 ba cd 2b 38 f0 a9 83 97 b2 4c 83 65 8f"
- "b6 c0 b4 14 0e f1 19 70 c4 63 0d 44 34 4e 76 ea"
- "ed 74 dc be e8 11 db f6 57 59 41 f0 8a 65 23 b8";
-
-// PKCS#1 v1.5 Signature Example 15.4
-
-char* message_4 =
- "29 03 55 84 ab 7e 02 26 a9 ec 4b 02 e8 dc f1 27 "
- "2d c9 a4 1d 73 e2 82 00 07 b0 f6 e2 1f ec cd 5b "
- "d9 db b9 ef 88 cd 67 58 76 9e e1 f9 56 da 7a d1 "
- "84 41 de 6f ab 83 86 db c6 93 ";
-
-char* signature_4 =
- "28 d8 e3 fc d5 dd db 21 ff bd 8d f1 63 0d 73 77"
- "aa 26 51 e1 4c ad 1c 0e 43 cc c5 2f 90 7f 94 6d"
- "66 de 72 54 e2 7a 6c 19 0e b0 22 ee 89 ec f6 22"
- "4b 09 7b 71 06 8c d6 07 28 a1 ae d6 4b 80 e5 45"
- "7b d3 10 6d d9 17 06 c9 37 c9 79 5f 2b 36 36 7f"
- "f1 53 dc 25 19 a8 db 9b df 2c 80 74 30 c4 51 de"
- "17 bb cd 0c e7 82 b3 e8 f1 02 4d 90 62 4d ea 7f"
- "1e ed c7 42 0b 7e 7c aa 65 77 ce f4 31 41 a7 26"
- "42 06 58 0e 44 a1 67 df 5e 41 ee a0 e6 9a 80 54"
- "54 c4 0e ef c1 3f 48 e4 23 d7 a3 2d 02 ed 42 c0"
- "ab 03 d0 a7 cf 70 c5 86 0a c9 2e 03 ee 00 5b 60"
- "ff 35 03 42 4b 98 cc 89 45 68 c7 c5 6a 02 33 55"
- "1c eb e5 88 cf 8b 01 67 b7 df 13 ad ca d8 28 67"
- "68 10 49 9c 70 4d a7 ae 23 41 4d 69 e3 c0 d2 db"
- "5d cb c2 61 3b c1 20 42 1f 9e 36 53 c5 a8 76 72"
- "97 64 3c 7e 07 40 de 01 63 55 45 3d 6c 95 ae 72";
-
-// PKCS#1 v1.5 Signature Example 15.5
-
-char* message_5 =
- "bd a3 a1 c7 90 59 ea e5 98 30 8d 3d f6 09 ";
-
-char* signature_5 =
- "a1 56 17 6c b9 67 77 c7 fb 96 10 5d bd 91 3b c4"
- "f7 40 54 f6 80 7c 60 08 a1 a9 56 ea 92 c1 f8 1c"
- "b8 97 dc 4b 92 ef 9f 4e 40 66 8d c7 c5 56 90 1a"
- "cb 6c f2 69 fe 61 5b 0f b7 2b 30 a5 13 38 69 23"
- "14 b0 e5 87 8a 88 c2 c7 77 4b d1 69 39 b5 ab d8"
- "2b 44 29 d6 7b d7 ac 8e 5e a7 fe 92 4e 20 a6 ec"
- "66 22 91 f2 54 8d 73 4f 66 34 86 8b 03 9a a5 f9"
- "d4 d9 06 b2 d0 cb 85 85 bf 42 85 47 af c9 1c 6e"
- "20 52 dd cd 00 1c 3e f8 c8 ee fc 3b 6b 2a 82 b6"
- "f9 c8 8c 56 f2 e2 c3 cb 0b e4 b8 0d a9 5e ba 37"
- "1d 8b 5f 60 f9 25 38 74 3d db b5 da 29 72 c7 1f"
- "e7 b9 f1 b7 90 26 8a 0e 77 0f c5 eb 4d 5d d8 52"
- "47 d4 8a e2 ec 3f 26 25 5a 39 85 52 02 06 a1 f2"
- "68 e4 83 e9 db b1 d5 ca b1 90 91 76 06 de 31 e7"
- "c5 18 2d 8f 15 1b f4 1d fe cc ae d7 cd e6 90 b2"
- "16 47 10 6b 49 0c 72 9d 54 a8 fe 28 02 a6 d1 26";
-
-// PKCS#1 v1.5 Signature Example 15.6
-
-char* message_6 =
- "c1 87 91 5e 4e 87 da 81 c0 8e d4 35 6a 0c ce ac "
- "1c 4f b5 c0 46 b4 52 81 b3 87 ec 28 f1 ab fd 56 "
- "7e 54 6b 23 6b 37 d0 1a e7 1d 3b 28 34 36 5d 3d "
- "f3 80 b7 50 61 b7 36 b0 13 0b 07 0b e5 8a e8 a4 "
- "6d 12 16 63 61 b6 13 db c4 7d fa eb 4c a7 46 45 "
- "6c 2e 88 83 85 52 5c ca 9d d1 c3 c7 a9 ad a7 6d "
- "6c ";;
-
-char* signature_6 =
- "9c ab 74 16 36 08 66 9f 75 55 a3 33 cf 19 6f e3"
- "a0 e9 e5 eb 1a 32 d3 4b b5 c8 5f f6 89 aa ab 0e"
- "3e 65 66 8e d3 b1 15 3f 94 eb 3d 8b e3 79 b8 ee"
- "f0 07 c4 a0 2c 70 71 ce 30 d8 bb 34 1e 58 c6 20"
- "f7 3d 37 b4 ec bf 48 be 29 4f 6c 9e 0e cb 5e 63"
- "fe c4 1f 12 0e 55 53 df a0 eb eb bb 72 64 0a 95"
- "37 ba dc b4 51 33 02 29 d9 f7 10 f6 2e 3e d8 ec"
- "78 4e 50 ee 1d 92 62 b4 26 71 34 00 11 d7 d0 98"
- "c6 f2 55 7b 21 31 fa 9b d0 25 46 36 59 7e 88 ec"
- "b3 5a 24 0e f0 fd 85 95 71 24 df 80 80 fe e1 e1"
- "49 af 93 99 89 e8 6b 26 c8 5a 58 81 fa e8 67 3d"
- "9f d4 08 00 dd 13 4e b9 bd b6 41 0f 42 0b 0a a9"
- "7b 20 ef cf 2e b0 c8 07 fa eb 83 a3 cc d9 b5 1d"
- "45 53 e4 1d fc 0d f6 ca 80 a1 e8 1d c2 34 bb 83"
- "89 dd 19 5a 38 b4 2d e4 ed c4 9d 34 64 78 b9 f1"
- "1f 05 57 20 5f 5b 0b d7 ff e9 c8 50 f3 96 d7 c4";;
-
-// PKCS#1 v1.5 Signature Example 15.7
-
-char* message_7 =
- "ab fa 2e cb 7d 29 bd 5b cb 99 31 ce 2b ad 2f 74 "
- "38 3e 95 68 3c ee 11 02 2f 08 e8 e7 d0 b8 fa 05 "
- "8b f9 eb 7e b5 f9 88 68 b5 bb 1f b5 c3 1c ed a3 "
- "a6 4f 1a 12 cd f2 0f cd 0e 5a 24 6d 7a 17 73 d8 "
- "db a0 e3 b2 77 54 5b ab e5 8f 2b 96 e3 f4 ed c1 "
- "8e ab f5 cd 2a 56 0f ca 75 fe 96 e0 7d 85 9d ef "
- "b2 56 4f 3a 34 f1 6f 11 e9 1b 3a 71 7b 41 af 53 "
- "f6 60 53 23 00 1a a4 06 c6 ";
-
-char* signature_7 =
- "c4 b4 37 bc f7 03 f3 52 e1 fa f7 4e b9 62 20 39"
- "42 6b 56 72 ca f2 a7 b3 81 c6 c4 f0 19 1e 7e 4a"
- "98 f0 ee bc d6 f4 17 84 c2 53 7f f0 f9 9e 74 98"
- "2c 87 20 1b fb c6 5e ae 83 2d b7 1d 16 da ca db"
- "09 77 e5 c5 04 67 9e 40 be 0f 9d b0 6f fd 84 8d"
- "d2 e5 c3 8a 7e c0 21 e7 f6 8c 47 df d3 8c c3 54"
- "49 3d 53 39 b4 59 5a 5b f3 1e 3f 8f 13 81 68 07"
- "37 3d f6 ad 0d c7 e7 31 e5 1a d1 9e b4 75 4b 13"
- "44 85 84 2f e7 09 d3 78 44 4d 8e 36 b1 72 4a 4f"
- "da 21 ca fe e6 53 ab 80 74 7f 79 52 ee 80 4d ea"
- "b1 03 9d 84 13 99 45 bb f4 be 82 00 87 53 f3 c5"
- "4c 78 21 a1 d2 41 f4 21 79 c7 94 ef 70 42 bb f9"
- "95 56 56 22 2e 45 c3 43 69 a3 84 69 7b 6a e7 42"
- "e1 8f a5 ca 7a ba d2 7d 9f e7 10 52 e3 31 0d 0f"
- "52 c8 d1 2e a3 3b f0 53 a3 00 f4 af c4 f0 98 df"
- "4e 6d 88 67 79 d6 45 94 d3 69 15 8f db c1 f6 94";
-
-// PKCS#1 v1.5 Signature Example 15.8
-
-char* message_8 =
- "df 40 44 a8 9a 83 e9 fc bf 12 62 54 0a e3 03 8b "
- "bc 90 f2 b2 62 8b f2 a4 46 7a c6 77 22 d8 54 6b "
- "3a 71 cb 0e a4 16 69 d5 b4 d6 18 59 c1 b4 e4 7c "
- "ec c5 93 3f 75 7e c8 6d b0 64 4e 31 18 12 d0 0f "
- "b8 02 f0 34 00 63 9c 0e 36 4d ae 5a eb c5 79 1b "
- "c6 55 76 23 61 bc 43 c5 3d 3c 78 86 76 8f 79 68 "
- "c1 c5 44 c6 f7 9f 7b e8 20 c7 e2 bd 2f 9d 73 e6 "
- "2d ed 6d 2e 93 7e 6a 6d ae f9 0e e3 7a 1a 52 a5 "
- "4f 00 e3 1a dd d6 48 94 cf 4c 02 e1 60 99 e2 9f "
- "9e b7 f1 a7 bb 7f 84 c4 7a 2b 59 48 13 be 02 a1 "
- "7b 7f c4 3b 34 c2 2c 91 92 52 64 12 6c 89 f8 6b "
- "b4 d8 7f 3e f1 31 29 6c 53 a3 08 e0 33 1d ac 8b "
- "af 3b 63 42 22 66 ec ef 2b 90 78 15 35 db da 41 "
- "cb d0 cf 22 a8 cb fb 53 2e c6 8f c6 af b2 ac 06 ";
-
-char* signature_8 =
- "14 14 b3 85 67 ae 6d 97 3e de 4a 06 84 2d cc 0e"
- "05 59 b1 9e 65 a4 88 9b db ab d0 fd 02 80 68 29"
- "13 ba cd 5d c2 f0 1b 30 bb 19 eb 81 0b 7d 9d ed"
- "32 b2 84 f1 47 bb e7 71 c9 30 c6 05 2a a7 34 13"
- "90 a8 49 f8 1d a9 cd 11 e5 ec cf 24 6d ba e9 5f"
- "a9 58 28 e9 ae 0c a3 55 03 25 32 6d ee f9 f4 95"
- "30 ba 44 1b ed 4a c2 9c 02 9c 9a 27 36 b1 a4 19"
- "0b 85 08 4a d1 50 42 6b 46 d7 f8 5b d7 02 f4 8d"
- "ac 5f 71 33 0b c4 23 a7 66 c6 5c c1 dc ab 20 d3"
- "d3 bb a7 2b 63 b3 ef 82 44 d4 2f 15 7c b7 e3 a8"
- "ba 5c 05 27 2c 64 cc 1a d2 1a 13 49 3c 39 11 f6"
- "0b 4e 9f 4e cc 99 00 eb 05 6e e5 9d 6f e4 b8 ff"
- "6e 80 48 cc c0 f3 8f 28 36 fd 3d fe 91 bf 4a 38"
- "6e 1e cc 2c 32 83 9f 0c a4 d1 b2 7a 56 8f a9 40"
- "dd 64 ad 16 bd 01 25 d0 34 8e 38 30 85 f0 88 94"
- "86 1c a1 89 87 22 7d 37 b4 2b 58 4a 83 57 cb 04";
-
-// PKCS#1 v1.5 Signature Example 15.9
-
-char* message_9 =
- "ea 94 1f f0 6f 86 c2 26 92 7f cf 0e 3b 11 b0 87 "
- "26 76 17 0c 1b fc 33 bd a8 e2 65 c7 77 71 f9 d0 "
- "85 01 64 a5 ee cb cc 5c e8 27 fb fa 07 c8 52 14 "
- "79 6d 81 27 e8 ca a8 18 94 ea 61 ce b1 44 9e 72 "
- "fe a0 a4 c9 43 b2 da 6d 9b 10 5f e0 53 b9 03 9a "
- "9c c5 3d 42 0b 75 39 fa b2 23 9c 6b 51 d1 7e 69 "
- "4c 95 7d 4b 0f 09 84 46 18 79 a0 75 9c 44 01 be "
- "ec d4 c6 06 a0 af bd 7a 07 6f 50 a2 df c2 80 7f "
- "24 f1 91 9b aa 77 46 d3 a6 4e 26 8e d3 f5 f8 e6 "
- "da 83 a2 a5 c9 15 2f 83 7c b0 78 12 bd 5b a7 d3 "
- "a0 79 85 de 88 11 3c 17 96 e9 b4 66 ec 29 9c 5a "
- "c1 05 9e 27 f0 94 15 ";
-
-char* signature_9 =
- "ce eb 84 cc b4 e9 09 92 65 65 07 21 ee a0 e8 ec"
- "89 ca 25 bd 35 4d 4f 64 56 49 67 be 9d 4b 08 b3"
- "f1 c0 18 53 9c 9d 37 1c f8 96 1f 22 91 fb e0 dc"
- "2f 2f 95 fe a4 7b 63 9f 1e 12 f4 bc 38 1c ef 0c"
- "2b 7a 7b 95 c3 ad f2 76 05 b7 f6 39 98 c3 cb ad"
- "54 28 08 c3 82 2e 06 4d 4a d1 40 93 67 9e 6e 01"
- "41 8a 6d 5c 05 96 84 cd 56 e3 4e d6 5a b6 05 b8"
- "de 4f cf a6 40 47 4a 54 a8 25 1b bb 73 26 a4 2d"
- "08 58 5c fc fc 95 67 69 b1 5b 6d 7f df 7d a8 4f"
- "81 97 6e aa 41 d6 92 38 0f f1 0e ae cf e0 a5 79"
- "68 29 09 b5 52 1f ad e8 54 d7 97 b8 a0 34 5b 9a"
- "86 4e 05 88 f6 ca dd bf 65 f1 77 99 8e 18 0d 1f"
- "10 24 43 e6 dc a5 3a 94 82 3c aa 9c 3b 35 f3 22"
- "58 3c 70 3a f6 74 76 15 9e c7 ec 93 d1 76 9b 30"
- "0a f0 e7 15 7d c2 98 c6 cd 2d ee 22 62 f8 cd dc"
- "10 f1 1e 01 74 14 71 bb fd 65 18 a1 75 73 45 75";
-
-// PKCS#1 v1.5 Signature Example 15.10
-
-char* message_10 =
- "d8 b8 16 45 c1 3c d7 ec f5 d0 0e d2 c9 1b 9a cd "
- "46 c1 55 68 e5 30 3c 4a 97 75 ed e7 6b 48 40 3d "
- "6b e5 6c 05 b6 b1 cf 77 c6 e7 5d e0 96 c5 cb 35 "
- "51 cb 6f a9 64 f3 c8 79 cf 58 9d 28 e1 da 2f 9d "
- "ec ";
-
-char* signature_10 =
- "27 45 07 4c a9 71 75 d9 92 e2 b4 47 91 c3 23 c5"
- "71 67 16 5c dd 8d a5 79 cd ef 46 86 b9 bb 40 4b"
- "d3 6a 56 50 4e b1 fd 77 0f 60 bf a1 88 a7 b2 4b"
- "0c 91 e8 81 c2 4e 35 b0 4d c4 dd 4c e3 85 66 bc"
- "c9 ce 54 f4 9a 17 5f c9 d0 b2 25 22 d9 57 90 47"
- "f9 ed 42 ec a8 3f 76 4a 10 16 39 97 94 7e 7d 2b"
- "52 ff 08 98 0e 7e 7c 22 57 93 7b 23 f3 d2 79 d4"
- "cd 17 d6 f4 95 54 63 73 d9 83 d5 36 ef d7 d1 b6"
- "71 81 ca 2c b5 0a c6 16 c5 c7 ab fb b9 26 0b 91"
- "b1 a3 8e 47 24 20 01 ff 45 2f 8d e1 0c a6 ea ea"
- "dc af 9e dc 28 95 6f 28 a7 11 29 1f c9 a8 08 78"
- "b8 ba 4c fe 25 b8 28 1c b8 0b c9 cd 6d 2b d1 82"
- "52 46 ee be 25 2d 99 57 ef 93 70 73 52 08 4e 6d"
- "36 d4 23 55 1b f2 66 a8 53 40 fb 4a 6a f3 70 88"
- "0a ab 07 15 3d 01 f4 8d 08 6d f0 bf be c0 5e 7b"
- "44 3b 97 e7 17 18 97 0e 2f 4b f6 20 23 e9 5b 67";
-
-// PKCS#1 v1.5 Signature Example 15.11
-
-char* message_11 =
- "e5 73 9b 6c 14 c9 2d 51 0d 95 b8 26 93 33 37 ff "
- "0d 24 ef 72 1a c4 ef 64 c2 ba d2 64 be 8b 44 ef "
- "a1 51 6e 08 a2 7e b6 b6 11 d3 30 1d f0 06 2d ae "
- "fc 73 a8 c0 d9 2e 2c 52 1f ac bc 7b 26 47 38 76 "
- "7e a6 fc 97 d5 88 a0 ba f6 ce 50 ad f7 9e 60 0b "
- "d2 9e 34 5f cb 1d ba 71 ac 5c 02 89 02 3f e4 a8 "
- "2b 46 a5 40 77 19 19 7d 2e 95 8e 35 31 fd 54 ae "
- "f9 03 aa bb 43 55 f8 83 18 99 4e d3 c3 dd 62 f4 "
- "20 a7 ";
-
-char* signature_11 =
- "be 40 a5 fb 94 f1 13 e1 b3 ef f6 b6 a3 39 86 f2"
- "02 e3 63 f0 74 83 b7 92 e6 8d fa 55 54 df 04 66"
- "cc 32 15 09 50 78 3b 4d 96 8b 63 9a 04 fd 2f b9"
- "7f 6e b9 67 02 1f 5a dc cb 9f ca 95 ac c8 f2 cd"
- "88 5a 38 0b 0a 4e 82 bc 76 07 64 db ab 88 c1 e6"
- "c0 25 5c aa 94 f2 32 19 9d 6f 59 7c c9 14 5b 00"
- "e3 d4 ba 34 6b 55 9a 88 33 ad 15 16 ad 51 63 f0"
- "16 af 6a 59 83 1c 82 ea 13 c8 22 4d 84 d0 76 5a"
- "9d 12 38 4d a4 60 a8 53 1b 4c 40 7e 04 f4 f3 50"
- "70 9e b9 f0 8f 5b 22 0f fb 45 ab f6 b7 5d 15 79"
- "fd 3f 1e b5 5f c7 5b 00 af 8b a3 b0 87 82 7f e9"
- "ae 9f b4 f6 c5 fa 63 03 1f e5 82 85 2f e2 83 4f"
- "9c 89 bf f5 3e 25 52 21 6b c7 c1 d4 a3 d5 dc 2b"
- "a6 95 5c d9 b1 7d 13 63 e7 fe e8 ed 76 29 75 3f"
- "f3 12 5e dd 48 52 1a e3 b9 b0 32 17 f4 49 6d 0d"
- "8e de 57 ac bc 5b d4 de ae 74 a5 6f 86 67 1d e2";
-
-// PKCS#1 v1.5 Signature Example 15.12
-
-char* message_12 =
- "7a f4 28 35 91 7a 88 d6 b3 c6 71 6b a2 f5 b0 d5 "
- "b2 0b d4 e2 e6 e5 74 e0 6a f1 ee f7 c8 11 31 be "
- "22 bf 81 28 b9 cb c6 ec 00 27 5b a8 02 94 a5 d1 "
- "17 2d 08 24 a7 9e 8f dd 83 01 83 e4 c0 0b 96 78 "
- "28 67 b1 22 7f ea 24 9a ad 32 ff c5 fe 00 7b c5 "
- "1f 21 79 2f 72 8d ed a8 b5 70 8a a9 9c ab ab 20 "
- "a4 aa 78 3e d8 6f 0f 27 b5 d5 63 f4 2e 07 15 8c "
- "ea 72 d0 97 aa 68 87 ec 41 1d d0 12 91 2a 5e 03 "
- "2b bf a6 78 50 71 44 bc c9 5f 39 b5 8b e7 bf d1 "
- "75 9a db 9a 91 fa 1d 6d 82 26 a8 34 3a 8b 84 9d "
- "ae 76 f7 b9 82 24 d5 9e 28 f7 81 f1 3e ce 60 5f "
- "84 f6 c9 0b ae 5f 8c f3 78 81 6f 40 20 a7 dd a1 "
- "be d9 0c 92 a2 36 34 d2 03 fa c3 fc d8 6d 68 d3 "
- "18 2a 7d 9c ca be 7b 07 95 f5 c6 55 e9 ac c4 e3 "
- "ec 18 51 40 d1 0c ef 05 34 64 ab 17 5c 83 bd 83 "
- "93 5e 3d ab af 34 62 ee be 63 d1 5f 57 3d 26 9a ";
-
-char* signature_12 =
- "4e 78 c5 90 2b 80 79 14 d1 2f a5 37 ae 68 71 c8"
- "6d b8 02 1e 55 d1 ad b8 eb 0c cf 1b 8f 36 ab 7d"
- "ad 1f 68 2e 94 7a 62 70 72 f0 3e 62 73 71 78 1d"
- "33 22 1d 17 4a be 46 0d bd 88 56 0c 22 f6 90 11"
- "6e 2f bb e6 e9 64 36 3a 3e 52 83 bb 5d 94 6e f1"
- "c0 04 7e ba 03 8c 75 6c 40 be 79 23 05 58 09 b0"
- "e9 f3 4a 03 a5 88 15 eb dd e7 67 93 1f 01 8f 6f"
- "18 78 f2 ef 4f 47 dd 37 40 51 dd 48 68 5d ed 6e"
- "fb 3e a8 02 1f 44 be 1d 7d 14 93 98 f9 8e a9 c0"
- "8d 62 88 8e bb 56 19 2d 17 74 7b 6b 8e 17 09 54"
- "31 f1 25 a8 a8 e9 96 2a a3 1c 28 52 64 e0 8f b2"
- "1a ac 33 6c e6 c3 8a a3 75 e4 2b c9 2a b0 ab 91"
- "03 84 31 e1 f9 2c 39 d2 af 5d ed 7e 43 bc 15 1e"
- "6e be a4 c3 e2 58 3a f3 43 7e 82 c4 3c 5e 3b 5b"
- "07 cf 03 59 68 3d 22 98 e3 59 48 ed 80 6c 06 3c"
- "60 6e a1 78 15 0b 1e fc 15 85 69 34 c7 25 5c fe";
-
-// PKCS#1 v1.5 Signature Example 15.13
-
-char* message_13 =
- "eb ae f3 f9 f2 3b df e5 fa 6b 8a f4 c2 08 c1 89 "
- "f2 25 1b f3 2f 5f 13 7b 9d e4 40 63 78 68 6b 3f "
- "07 21 f6 2d 24 cb 86 88 d6 fc 41 a2 7c ba e2 1d "
- "30 e4 29 fe ac c7 11 19 41 c2 77 ";
-
-char* signature_13 =
- "c4 8d be f5 07 11 4f 03 c9 5f af be b4 df 1b fa"
- "88 e0 18 4a 33 cc 4f 8a 9a 10 35 ff 7f 82 2a 5e"
- "38 cd a1 87 23 91 5f f0 78 24 44 29 e0 f6 08 1c"
- "14 fd 83 33 1f a6 5c 6b a7 bb 9a 12 db f6 62 23"
- "74 cd 0c a5 7d e3 77 4e 2b d7 ae 82 36 77 d0 61"
- "d5 3a e9 c4 04 0d 2d a7 ef 70 14 f3 bb dc 95 a3"
- "61 a4 38 55 c8 ce 9b 97 ec ab ce 17 4d 92 62 85"
- "14 2b 53 4a 30 87 f9 f4 ef 74 51 1e c7 42 b0 d5"
- "68 56 03 fa f4 03 b5 07 2b 98 5d f4 6a df 2d 25"
- "29 a0 2d 40 71 1e 21 90 91 70 52 37 1b 79 b7 49"
- "b8 3a bf 0a e2 94 86 c3 f2 f6 24 77 b2 bd 36 2b"
- "03 9c 01 3c 0c 50 76 ef 52 0d bb 40 5f 42 ce e9"
- "54 25 c3 73 a9 75 e1 cd d0 32 c4 96 22 c8 50 79"
- "b0 9e 88 da b2 b1 39 69 ef 7a 72 39 73 78 10 40"
- "45 9f 57 d5 01 36 38 48 3d e2 d9 1c b3 c4 90 da"
- "81 c4 6d e6 cd 76 ea 8a 0c 8f 6f e3 31 71 2d 24";
-
-// PKCS#1 v1.5 Signature Example 15.14
-
-char* message_14 =
- "c5 a2 71 12 78 76 1d fc dd 4f 0c 99 e6 f5 61 9d "
- "6c 48 b5 d4 c1 a8 09 82 fa a6 b4 cf 1c f7 a6 0f "
- "f3 27 ab ef 93 c8 01 42 9e fd e0 86 40 85 81 46 "
- "10 56 ac c3 3f 3d 04 f5 ad a2 12 16 ca cd 5f d1 "
- "f9 ed 83 20 3e 0e 2f e6 13 8e 3e ae 84 24 e5 91 "
- "5a 08 3f 3f 7a b7 60 52 c8 be 55 ae 88 2d 6e c1 "
- "48 2b 1e 45 c5 da e9 f4 10 15 40 53 27 02 2e c3 "
- "2f 0e a2 42 97 63 b2 55 04 3b 19 58 ee 3c f6 d6 "
- "39 83 59 6e b3 85 84 4f 85 28 cc 9a 98 65 83 5d "
- "c5 11 3c 02 b8 0d 0f ca 68 aa 25 e7 2b ca ae b3 "
- "cf 9d 79 d8 4f 98 4f d4 17 ";
-
-char* signature_14 =
- "6b d5 25 7a a0 66 11 fb 46 60 08 7c b4 bc 4a 9e"
- "44 91 59 d3 16 52 bd 98 08 44 da f3 b1 c7 b3 53"
- "f8 e5 61 42 f7 ea 98 57 43 3b 18 57 3b 4d ee de"
- "81 8a 93 b0 29 02 97 78 3f 1a 2f 23 cb c7 27 97"
- "a6 72 53 7f 01 f6 24 84 cd 41 62 c3 21 4b 9a c6"
- "28 22 4c 5d e0 1f 32 bb 9b 76 b2 73 54 f2 b1 51"
- "d0 e8 c4 21 3e 46 15 ad 0b c7 1f 51 5e 30 0d 6a"
- "64 c6 74 34 11 ff fd e8 e5 ff 19 0e 54 92 30 43"
- "12 6e cf c4 c4 53 90 22 66 8f b6 75 f2 5c 07 e2"
- "00 99 ee 31 5b 98 d6 af ec 4b 1a 9a 93 dc 33 49"
- "6a 15 bd 6f de 16 63 a7 d4 9b 9f 1e 63 9d 38 66"
- "4b 37 a0 10 b1 f3 5e 65 86 82 d9 cd 63 e5 7d e0"
- "f1 5e 8b dd 09 65 58 f0 7e c0 ca a2 18 a8 c0 6f"
- "47 88 45 39 40 28 7c 9d 34 b6 d4 0a 3f 09 bf 77"
- "99 fe 98 ae 4e b4 9f 3f f4 1c 50 40 a5 0c ef c9"
- "bd f2 39 4b 74 9c f1 64 48 0d f1 ab 68 80 27 3b";
-
-// PKCS#1 v1.5 Signature Example 15.15
-
-char* message_15 =
- "9b f8 aa 25 3b 87 2e a7 7a 7e 23 47 6b e2 6b 23 "
- "29 57 8c f6 ac 9e a2 80 5b 35 7f 6f c3 ad 13 0d "
- "ba eb 3d 86 9a 13 cc e7 a8 08 bb bb c9 69 85 7e "
- "03 94 5c 7b b6 1d f1 b5 c2 58 9b 8e 04 6c 2a 5d "
- "7e 40 57 b1 a7 4f 24 c7 11 21 63 64 28 85 29 ec "
- "95 70 f2 51 97 21 3b e1 f5 c2 e5 96 f8 bf 8b 2c "
- "f3 cb 38 aa 56 ff e5 e3 1d f7 39 58 20 e9 4e cf "
- "3b 11 89 a9 65 dc f9 a9 cb 42 98 d3 c8 8b 29 23 "
- "c1 9f c6 bc 34 aa ce ca d4 e0 93 1a 7c 4e 5d 73 "
- "dc 86 df a7 98 a8 47 6d 82 46 3e ef aa 90 a8 a9 "
- "19 2a b0 8b 23 08 8d d5 8e 12 80 f7 d7 2e 45 48 "
- "39 6b aa c1 12 25 2d d5 c5 34 6a db 20 04 a2 f7 "
- "10 1c cc 89 9c c7 fa fa e8 bb e2 95 73 88 96 a5 "
- "b2 01 22 85 01 4e f6 ";
-
-char* signature_15 =
- "27 f7 f4 da 9b d6 10 10 6e f5 7d 32 38 3a 44 8a"
- "8a 62 45 c8 3d c1 30 9c 6d 77 0d 35 7b a8 9e 73"
- "f2 ad 08 32 06 2e b0 fe 0a c9 15 57 5b cd 6b 8b"
- "ca db 4e 2b a6 fa 9d a7 3a 59 17 51 52 b2 d4 fe"
- "72 b0 70 c9 b7 37 9e 50 00 0e 55 e6 c2 69 f6 65"
- "8c 93 79 72 79 7d 3a dd 69 f1 30 e3 4b 85 bd ec"
- "9f 3a 9b 39 22 02 d6 f3 e4 30 d0 9c ac a8 22 77"
- "59 ab 82 5f 70 12 d2 ff 4b 5b 62 c8 50 4d ba d8"
- "55 c0 5e dd 5c ab 5a 4c cc dc 67 f0 1d d6 51 7c"
- "7d 41 c4 3e 2a 49 57 af f1 9d b6 f1 8b 17 85 9a"
- "f0 bc 84 ab 67 14 6e c1 a4 a6 0a 17 d7 e0 5f 8b"
- "4f 9c ed 6a d1 09 08 d8 d7 8f 7f c8 8b 76 ad c8"
- "29 0f 87 da f2 a7 be 10 ae 40 85 21 39 5d 54 ed"
- "25 56 fb 76 61 85 4a 73 0c e3 d8 2c 71 a8 d4 93"
- "ec 49 a3 78 ac 8a 3c 74 43 9f 7c c5 55 ba 13 f8"
- "59 07 08 90 ee 18 ff 65 8f a4 d7 41 96 9d 70 a5";
-
-// PKCS#1 v1.5 Signature Example 15.16
-
-char* message_16 =
- "32 47 48 30 e2 20 37 54 c8 bf 06 81 dc 4f 84 2a "
- "fe 36 09 30 37 86 16 c1 08 e8 33 65 6e 56 40 c8 "
- "68 56 88 5b b0 5d 1e b9 43 8e fe de 67 92 63 de "
- "07 cb 39 55 3f 6a 25 e0 06 b0 a5 23 11 a0 63 ca "
- "08 82 66 d2 56 4f f6 49 0c 46 b5 60 98 18 54 8f "
- "88 76 4d ad 34 a2 5e 3a 85 d5 75 02 3f 0b 9e 66 "
- "50 48 a0 3c 35 05 79 a9 d3 24 46 c7 bb 96 cc 92 "
- "e0 65 ab 94 d3 c8 95 2e 8d f6 8e f0 d9 fa 45 6b "
- "3a 06 bb 80 e3 bb c4 b2 8e 6a 94 b6 d0 ff 76 96 "
- "a6 4e fe 05 e7 35 fe a0 25 d7 bd bc 41 39 f3 a3 "
- "b5 46 07 5c ba 7e fa 94 73 74 d3 f0 ac 80 a6 8d "
- "76 5f 5d f6 21 0b ca 06 9a 2d 88 64 7a f7 ea 04 "
- "2d ac 69 0c b5 73 78 ec 07 77 61 4f b8 b6 5f f4 "
- "53 ca 6b 7d ce 60 98 45 1a 2f 8c 0d a9 bf ec f1 "
- "fd f3 91 bb aa 4e 2a 91 ca 18 a1 12 1a 75 23 a2 "
- "ab d4 25 14 f4 89 e8 ";
-
-char* signature_16 =
- "69 17 43 72 57 c2 2c cb 54 03 29 0c 3d ee 82 d9"
- "cf 75 50 b3 1b d3 1c 51 bd 57 bf d3 5d 45 2a b4"
- "db 7c 4b e6 b2 e2 5a c9 a5 9a 1d 2a 7f eb 62 7f"
- "0a fd 49 76 b3 00 3c c9 cf fd 88 96 50 5e c3 82"
- "f2 65 10 4d 4c f8 c9 32 fa 9f e8 6e 00 87 07 95"
- "99 12 38 9d a4 b2 d6 b3 69 b3 6a 5e 72 e2 9d 24"
- "c9 a9 8c 9d 31 a3 ab 44 e6 43 e6 94 12 66 a4 7a"
- "45 e3 44 6c e8 77 6a be 24 1a 8f 5f c6 42 3b 24"
- "b1 ff 25 0d c2 c3 a8 17 23 53 56 10 77 e8 50 a7"
- "69 b2 5f 03 25 da c8 89 65 a3 b9 b4 72 c4 94 e9"
- "5f 71 9b 4e ac 33 2c aa 7a 65 c7 df e4 6d 9a a7"
- "e6 e0 0f 52 5f 30 3d d6 3a b7 91 92 18 90 18 68"
- "f9 33 7f 8c d2 6a af e6 f3 3b 7f b2 c9 88 10 af"
- "19 f7 fc b2 82 ba 15 77 91 2c 1d 36 89 75 fd 5d"
- "44 0b 86 e1 0c 19 97 15 fa 0b 6f 42 50 b5 33 73"
- "2d 0b ef e1 54 51 50 fc 47 b8 76 de 09 b0 0a 94";
-
-// PKCS#1 v1.5 Signature Example 15.17
-
-char* message_17 =
- "00 8e 59 50 5e af b5 50 aa e5 e8 45 58 4c eb b0 "
- "0b 6d e1 73 3e 9f 95 d4 2c 88 2a 5b be b5 ce 1c "
- "57 e1 19 e7 c0 d4 da ca 9f 1f f7 87 02 17 f7 cf "
- "d8 a6 b3 73 97 7c ac 9c ab 8e 71 e4 20 ";
-
-char* signature_17 =
- "92 25 03 b6 73 ee 5f 3e 69 1e 1c a8 5e 9f f4 17"
- "3c f7 2b 05 ac 2c 13 1d a5 60 35 93 e3 bc 25 9c"
- "94 c1 f7 d3 a0 6a 5b 98 91 bf 11 3f a3 9e 59 ff"
- "7c 1e d6 46 5e 90 80 49 cb 89 e4 e1 25 cd 37 d2"
- "ff d9 22 7a 41 b4 a0 a1 9c 0a 44 fb bf 3d e5 5b"
- "ab 80 20 87 a3 bb 8d 4f f6 68 ee 6b bb 8a d8 9e"
- "68 57 a7 9a 9c 72 78 19 90 df cf 92 cd 51 94 04"
- "c9 50 f1 3d 11 43 c3 18 4f 1d 25 0c 90 e1 7a c6"
- "ce 36 16 3b 98 95 62 7a d6 ff ec 14 22 44 1f 55"
- "e4 49 9d ba 9b e8 95 46 ae 8b c6 3c ca 01 dd 08"
- "46 3a e7 f1 fc e3 d8 93 99 69 38 77 8c 18 12 e6"
- "74 ad 9c 30 9c 5a cc a3 fd e4 4e 7d d8 69 59 93"
- "e9 c1 fa 87 ac da 99 ec e5 c8 49 9e 46 89 57 ad"
- "66 35 9b f1 2a 51 ad be 78 d3 a2 13 b4 49 bf 0b"
- "5f 8d 4d 49 6a cf 03 d3 03 3b 7c cd 19 6b c2 2f"
- "68 fb 7b ef 4f 69 7c 5e a2 b3 50 62 f4 8a 36 dd";
-
-// PKCS#1 v1.5 Signature Example 15.18
-
-char* message_18 =
- "6a bc 54 cf 8d 1d ff 1f 53 b1 7d 81 60 36 88 78 "
- "a8 78 8c c6 d2 2f a5 c2 25 8c 88 e6 60 b0 9a 89 "
- "33 f9 f2 c0 50 4d da dc 21 f6 e7 5e 0b 83 3b eb "
- "55 52 29 de e6 56 b9 04 7b 92 f6 2e 76 b8 ff cc "
- "60 da b0 6b 80 ";
-
-char* signature_18 =
- "0b 6d af 42 f7 a8 62 14 7e 41 74 93 c2 c4 01 ef"
- "ae 32 63 6a b4 cb d4 41 92 bb f5 f1 95 b5 0a e0"
- "96 a4 75 a1 61 4f 0a 9f a8 f7 a0 26 cb 46 c6 50"
- "6e 51 8e 33 d8 3e 56 47 7a 87 5a ca 8c 7e 71 4c"
- "e1 bd bd 61 ef 5d 53 52 39 b3 3f 2b fd d6 17 71"
- "ba b6 27 76 d7 81 71 a1 42 3c ea 87 31 f8 2e 60"
- "76 6d 64 54 26 56 20 b1 5f 5c 5a 58 4f 55 f9 5b"
- "80 2f e7 8c 57 4e d5 da cf c8 31 f3 cf 2b 05 02"
- "c0 b2 98 f2 5c cf 11 f9 73 b3 1f 85 e4 74 42 19"
- "85 f3 cf f7 02 df 39 46 ef 0a 66 05 68 21 11 b2"
- "f5 5b 1f 8a b0 d2 ea 3a 68 3c 69 98 5e ad 93 ed"
- "44 9e a4 8f 03 58 dd f7 08 02 cb 41 de 2f d8 3f"
- "3c 80 80 82 d8 49 36 94 8e 0c 84 a1 31 b4 92 78"
- "27 46 05 27 bb 5c d2 4b fa b7 b4 8e 07 1b 24 17"
- "19 30 f9 97 63 27 2f 97 97 bc b7 6f 1d 24 81 57"
- "55 58 fc f2 60 b1 f0 e5 54 eb b3 df 3c fc b9 58";
-
-// PKCS#1 v1.5 Signature Example 15.19
-
-char* message_19 =
- "af 2d 78 15 2c f1 0e fe 01 d2 74 f2 17 b1 77 f6 "
- "b0 1b 5e 74 9f 15 67 71 5d a3 24 85 9c d3 dd 88 "
- "db 84 8e c7 9f 48 db ba 7b 6f 1d 33 11 1e f3 1b "
- "64 89 9e 73 91 c2 bf fd 69 f4 90 25 cf 20 1f c5 "
- "85 db d1 54 2c 1c 77 8a 2c e7 a7 ee 10 8a 30 9f "
- "ec a2 6d 13 3a 5f fe dc 4e 86 9d cd 76 56 59 6a "
- "c8 42 7e a3 ef 6e 3f d7 8f e9 9d 8d dc 71 d8 39 "
- "f6 78 6e 0d a6 e7 86 bd 62 b3 a4 f1 9b 89 1a 56 "
- "15 7a 55 4e c2 a2 b3 9e 25 a1 d7 c7 d3 73 21 c7 "
- "a1 d9 46 cf 4f be 75 8d 92 76 f0 85 63 44 9d 67 "
- "41 4a 2c 03 0f 42 51 cf e2 21 3d 04 a5 41 06 37 "
- "87 ";
-
-char* signature_19 =
- "20 9c 61 15 78 57 38 7b 71 e2 4b f3 dd 56 41 45"
- "50 50 3b ec 18 0f f5 3b dd 9b ac 06 2a 2d 49 95"
- "09 bf 99 12 81 b7 95 27 df 91 36 61 5b 7a 6d 9d"
- "b3 a1 03 b5 35 e0 20 2a 2c ac a1 97 a7 b7 4e 53"
- "56 f3 dd 59 5b 49 ac fd 9d 30 04 9a 98 ca 88 f6"
- "25 bc a1 d5 f2 2a 39 2d 8a 74 9e fb 6e ed 9b 78"
- "21 d3 11 0a c0 d2 44 19 9e cb 4a a3 d7 35 a8 3a"
- "2e 88 93 c6 bf 85 81 38 3c ca ee 83 46 35 b7 fa"
- "1f af fa 45 b1 3d 15 c1 da 33 af 71 e8 93 03 d6"
- "80 90 ff 62 ee 61 5f df 5a 84 d1 20 71 1d a5 3c"
- "28 89 19 8a b3 83 17 a9 73 4a b2 7d 67 92 4c ea"
- "74 15 6f f9 9b ef 98 76 bb 5c 33 9e 93 74 52 83"
- "e1 b3 4e 07 22 26 b8 80 45 e0 17 e9 f0 5b 2a 8c"
- "41 67 40 25 8e 22 3b 26 90 02 74 91 73 22 73 f3"
- "22 9d 9e f2 b1 b3 80 7e 32 10 18 92 0a d3 e5 3d"
- "ae 47 e6 d9 39 5c 18 4b 93 a3 74 c6 71 fa a2 ce";
-
-// PKCS#1 v1.5 Signature Example 15.20
-
-char* message_20 =
- "40 ee 99 24 58 d6 f6 14 86 d2 56 76 a9 6d d2 cb "
- "93 a3 7f 04 b1 78 48 2f 2b 18 6c f8 82 15 27 0d "
- "ba 29 d7 86 d7 74 b0 c5 e7 8c 7f 6e 56 a9 56 e7 "
- "f7 39 50 a2 b0 c0 c1 0a 08 db cd 67 e5 b2 10 bb "
- "21 c5 8e 27 67 d4 4f 7d d4 01 4e 39 66 14 3b f7 "
- "e3 d6 6f f0 c0 9b e4 c5 5f 93 b3 99 94 b8 51 8d "
- "9c 1d 76 d5 b4 73 74 de a0 8f 15 7d 57 d7 06 34 "
- "97 8f 38 56 e0 e5 b4 81 af bb db 5a 3a c4 8d 48 "
- "4b e9 2c 93 de 22 91 78 35 4c 2d e5 26 e9 c6 5a "
- "31 ed e1 ef 68 cb 63 98 d7 91 16 84 fe c0 ba bc "
- "3a 78 1a 66 66 07 83 50 69 74 d0 e1 48 25 10 1c "
- "3b fa ea ";
-
-char* signature_20 =
- "92 75 02 b8 24 af c4 25 13 ca 65 70 de 33 8b 8a"
- "64 c3 a8 5e b8 28 d3 19 36 24 f2 7e 8b 10 29 c5"
- "5c 11 9c 97 33 b1 8f 58 49 b3 50 09 18 bc c0 05"
- "51 d9 a8 fd f5 3a 97 74 9f a8 dc 48 0d 6f e9 74"
- "2a 58 71 f9 73 92 65 28 97 2a 1a f4 9e 39 25 b0"
- "ad f1 4a 84 27 19 b4 a5 a2 d8 9f a9 c0 b6 60 5d"
- "21 2b ed 1e 67 23 b9 34 06 ad 30 e8 68 29 a5 c7"
- "19 b8 90 b3 89 30 6d c5 50 64 86 ee 2f 36 a8 df"
- "e0 a9 6a f6 78 c9 cb d6 af f3 97 ca 20 0e 3e dc"
- "1e 36 bd 2f 08 b3 1d 54 0c 0c b2 82 a9 55 9e 4a"
- "dd 4f c9 e6 49 2e ed 0c cb d3 a6 98 2e 5f aa 2d"
- "dd 17 be 47 41 7c 80 b4 e5 45 2d 31 f7 24 01 a0"
- "42 32 51 09 54 4d 95 4c 01 93 90 79 d4 09 a5 c3"
- "78 d7 51 2d fc 2d 2a 71 ef cc 34 32 a7 65 d1 c6"
- "a5 2c fc e8 99 cd 79 b1 5b 4f c3 72 36 41 ef 6b"
- "d0 0a cc 10 40 7e 5d f5 8d d1 c3 c5 c5 59 a5 06";
-
-
-unsigned char* parsehex(char* str, int* len) {
- // result can't be longer than input
- unsigned char* result = malloc(strlen(str));
-
- unsigned char* p = result;
- *len = 0;
-
- while (*str) {
- int b;
-
- while (isspace(*str)) str++;
-
- switch (*str) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- b = (*str - '0') << 4; break;
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- b = (*str - 'a' + 10) << 4; break;
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- b = (*str - 'A' + 10) << 4; break;
- case '\0':
- return result;
- default:
- return NULL;
- }
- str++;
-
- while (isspace(*str)) str++;
-
- switch (*str) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- b |= *str - '0'; break;
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- b |= *str - 'a' + 10; break;
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- b |= *str - 'A' + 10; break;
- default:
- return NULL;
- }
- str++;
-
- *p++ = b;
- ++*len;
- }
-
- return result;
-}
-
-
-int main(int arg __unused, char** argv __unused) {
-
- unsigned char hash[SHA_DIGEST_SIZE];
-
- unsigned char* message;
- int mlen;
- unsigned char* signature;
- int slen;
-
-#define TEST_MESSAGE(n) do {\
- message = parsehex(message_##n, &mlen); \
- SHA_hash(message, mlen, hash); \
- signature = parsehex(signature_##n, &slen); \
- int result = RSA_verify(&key_15, signature, slen, hash, sizeof(hash)); \
- printf("message %d: %s\n", n, result ? "verified" : "not verified"); \
- success = success && result; \
- } while(0)
-
- int success = 1;
-
- TEST_MESSAGE(1);
- TEST_MESSAGE(2);
- TEST_MESSAGE(3);
- TEST_MESSAGE(4);
- TEST_MESSAGE(5);
- TEST_MESSAGE(6);
- TEST_MESSAGE(7);
- TEST_MESSAGE(8);
- TEST_MESSAGE(9);
- TEST_MESSAGE(10);
- TEST_MESSAGE(11);
- TEST_MESSAGE(12);
- TEST_MESSAGE(13);
- TEST_MESSAGE(14);
- TEST_MESSAGE(15);
- TEST_MESSAGE(16);
- TEST_MESSAGE(17);
- TEST_MESSAGE(18);
- TEST_MESSAGE(19);
- TEST_MESSAGE(20);
-
- printf("\n%s\n\n", success ? "PASS" : "FAIL");
-
- return !success;
-}
diff --git a/libmincrypt/tools/DumpPublicKey.java b/libmincrypt/tools/DumpPublicKey.java
deleted file mode 100644
index 3eb1398..0000000
--- a/libmincrypt/tools/DumpPublicKey.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dumpkey;
-
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-
-import java.io.FileInputStream;
-import java.math.BigInteger;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.KeyStore;
-import java.security.Key;
-import java.security.PublicKey;
-import java.security.Security;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.ECPoint;
-
-/**
- * Command line tool to extract RSA public keys from X.509 certificates
- * and output source code with data initializers for the keys.
- * @hide
- */
-class DumpPublicKey {
- /**
- * @param key to perform sanity checks on
- * @return version number of key. Supported versions are:
- * 1: 2048-bit RSA key with e=3 and SHA-1 hash
- * 2: 2048-bit RSA key with e=65537 and SHA-1 hash
- * 3: 2048-bit RSA key with e=3 and SHA-256 hash
- * 4: 2048-bit RSA key with e=65537 and SHA-256 hash
- * @throws Exception if the key has the wrong size or public exponent
- */
- static int checkRSA(RSAPublicKey key, boolean useSHA256) throws Exception {
- BigInteger pubexp = key.getPublicExponent();
- BigInteger modulus = key.getModulus();
- int version;
-
- if (pubexp.equals(BigInteger.valueOf(3))) {
- version = useSHA256 ? 3 : 1;
- } else if (pubexp.equals(BigInteger.valueOf(65537))) {
- version = useSHA256 ? 4 : 2;
- } else {
- throw new Exception("Public exponent should be 3 or 65537 but is " +
- pubexp.toString(10) + ".");
- }
-
- if (modulus.bitLength() != 2048) {
- throw new Exception("Modulus should be 2048 bits long but is " +
- modulus.bitLength() + " bits.");
- }
-
- return version;
- }
-
- /**
- * @param key to perform sanity checks on
- * @return version number of key. Supported versions are:
- * 5: 256-bit EC key with curve NIST P-256
- * @throws Exception if the key has the wrong size or public exponent
- */
- static int checkEC(ECPublicKey key) throws Exception {
- if (key.getParams().getCurve().getField().getFieldSize() != 256) {
- throw new Exception("Curve must be NIST P-256");
- }
-
- return 5;
- }
-
- /**
- * Perform sanity check on public key.
- */
- static int check(PublicKey key, boolean useSHA256) throws Exception {
- if (key instanceof RSAPublicKey) {
- return checkRSA((RSAPublicKey) key, useSHA256);
- } else if (key instanceof ECPublicKey) {
- if (!useSHA256) {
- throw new Exception("Must use SHA-256 with EC keys!");
- }
- return checkEC((ECPublicKey) key);
- } else {
- throw new Exception("Unsupported key class: " + key.getClass().getName());
- }
- }
-
- /**
- * @param key to output
- * @return a String representing this public key. If the key is a
- * version 1 key, the string will be a C initializer; this is
- * not true for newer key versions.
- */
- static String printRSA(RSAPublicKey key, boolean useSHA256) throws Exception {
- int version = check(key, useSHA256);
-
- BigInteger N = key.getModulus();
-
- StringBuilder result = new StringBuilder();
-
- int nwords = N.bitLength() / 32; // # of 32 bit integers in modulus
-
- if (version > 1) {
- result.append("v");
- result.append(Integer.toString(version));
- result.append(" ");
- }
-
- result.append("{");
- result.append(nwords);
-
- BigInteger B = BigInteger.valueOf(0x100000000L); // 2^32
- BigInteger N0inv = B.subtract(N.modInverse(B)); // -1 / N[0] mod 2^32
-
- result.append(",0x");
- result.append(N0inv.toString(16));
-
- BigInteger R = BigInteger.valueOf(2).pow(N.bitLength());
- BigInteger RR = R.multiply(R).mod(N); // 2^4096 mod N
-
- // Write out modulus as little endian array of integers.
- result.append(",{");
- for (int i = 0; i < nwords; ++i) {
- long n = N.mod(B).longValue();
- result.append(n);
-
- if (i != nwords - 1) {
- result.append(",");
- }
-
- N = N.divide(B);
- }
- result.append("}");
-
- // Write R^2 as little endian array of integers.
- result.append(",{");
- for (int i = 0; i < nwords; ++i) {
- long rr = RR.mod(B).longValue();
- result.append(rr);
-
- if (i != nwords - 1) {
- result.append(",");
- }
-
- RR = RR.divide(B);
- }
- result.append("}");
-
- result.append("}");
- return result.toString();
- }
-
- /**
- * @param key to output
- * @return a String representing this public key. If the key is a
- * version 1 key, the string will be a C initializer; this is
- * not true for newer key versions.
- */
- static String printEC(ECPublicKey key) throws Exception {
- int version = checkEC(key);
-
- StringBuilder result = new StringBuilder();
-
- result.append("v");
- result.append(Integer.toString(version));
- result.append(" ");
-
- BigInteger X = key.getW().getAffineX();
- BigInteger Y = key.getW().getAffineY();
- int nbytes = key.getParams().getCurve().getField().getFieldSize() / 8; // # of 32 bit integers in X coordinate
-
- result.append("{");
- result.append(nbytes);
-
- BigInteger B = BigInteger.valueOf(0x100L); // 2^8
-
- // Write out Y coordinate as array of characters.
- result.append(",{");
- for (int i = 0; i < nbytes; ++i) {
- long n = X.mod(B).longValue();
- result.append(n);
-
- if (i != nbytes - 1) {
- result.append(",");
- }
-
- X = X.divide(B);
- }
- result.append("}");
-
- // Write out Y coordinate as array of characters.
- result.append(",{");
- for (int i = 0; i < nbytes; ++i) {
- long n = Y.mod(B).longValue();
- result.append(n);
-
- if (i != nbytes - 1) {
- result.append(",");
- }
-
- Y = Y.divide(B);
- }
- result.append("}");
-
- result.append("}");
- return result.toString();
- }
-
- static String print(PublicKey key, boolean useSHA256) throws Exception {
- if (key instanceof RSAPublicKey) {
- return printRSA((RSAPublicKey) key, useSHA256);
- } else if (key instanceof ECPublicKey) {
- return printEC((ECPublicKey) key);
- } else {
- throw new Exception("Unsupported key class: " + key.getClass().getName());
- }
- }
-
- public static void main(String[] args) {
- if (args.length < 1) {
- System.err.println("Usage: DumpPublicKey certfile ... > source.c");
- System.exit(1);
- }
- Security.addProvider(new BouncyCastleProvider());
- try {
- for (int i = 0; i < args.length; i++) {
- FileInputStream input = new FileInputStream(args[i]);
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- X509Certificate cert = (X509Certificate) cf.generateCertificate(input);
-
- boolean useSHA256 = false;
- String sigAlg = cert.getSigAlgName();
- if ("SHA1withRSA".equals(sigAlg) || "MD5withRSA".equals(sigAlg)) {
- // SignApk has historically accepted "MD5withRSA"
- // certificates, but treated them as "SHA1withRSA"
- // anyway. Continue to do so for backwards
- // compatibility.
- useSHA256 = false;
- } else if ("SHA256withRSA".equals(sigAlg) || "SHA256withECDSA".equals(sigAlg)) {
- useSHA256 = true;
- } else {
- System.err.println(args[i] + ": unsupported signature algorithm \"" +
- sigAlg + "\"");
- System.exit(1);
- }
-
- PublicKey key = cert.getPublicKey();
- check(key, useSHA256);
- System.out.print(print(key, useSHA256));
- System.out.println(i < args.length - 1 ? "," : "");
- }
- } catch (Exception e) {
- e.printStackTrace();
- System.exit(1);
- }
- System.exit(0);
- }
-}
diff --git a/libmincrypt/tools/DumpPublicKey.mf b/libmincrypt/tools/DumpPublicKey.mf
deleted file mode 100644
index 7bb3bc8..0000000
--- a/libmincrypt/tools/DumpPublicKey.mf
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.dumpkey.DumpPublicKey
diff --git a/libnativebridge/native_bridge.cc b/libnativebridge/native_bridge.cc
index 32a65ea..ecfd719 100644
--- a/libnativebridge/native_bridge.cc
+++ b/libnativebridge/native_bridge.cc
@@ -231,8 +231,10 @@
static const char* kRuntimeISA = "arm";
#elif defined(__aarch64__)
static const char* kRuntimeISA = "arm64";
-#elif defined(__mips__)
+#elif defined(__mips__) && !defined(__LP64__)
static const char* kRuntimeISA = "mips";
+#elif defined(__mips__) && defined(__LP64__)
+static const char* kRuntimeISA = "mips64";
#elif defined(__i386__)
static const char* kRuntimeISA = "x86";
#elif defined(__x86_64__)
diff --git a/libnativebridge/tests/NeedsNativeBridge_test.cpp b/libnativebridge/tests/NeedsNativeBridge_test.cpp
index e1c0876..2067ed2 100644
--- a/libnativebridge/tests/NeedsNativeBridge_test.cpp
+++ b/libnativebridge/tests/NeedsNativeBridge_test.cpp
@@ -18,15 +18,17 @@
namespace android {
-static const char* kISAs[] = { "arm", "arm64", "mips", "x86", "x86_64", "random", "64arm", "64_x86",
- "64_x86_64", "", "reallylongstringabcd", nullptr };
+static const char* kISAs[] = { "arm", "arm64", "mips", "mips64", "x86", "x86_64", "random", "64arm",
+ "64_x86", "64_x86_64", "", "reallylongstringabcd", nullptr };
#if defined(__arm__)
static const char* kRuntimeISA = "arm";
#elif defined(__aarch64__)
static const char* kRuntimeISA = "arm64";
-#elif defined(__mips__)
+#elif defined(__mips__) && !defined(__LP64__)
static const char* kRuntimeISA = "mips";
+#elif defined(__mips__) && defined(__LP64__)
+static const char* kRuntimeISA = "mips64";
#elif defined(__i386__)
static const char* kRuntimeISA = "x86";
#elif defined(__x86_64__)
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index f28a693..81dc316 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -40,10 +40,6 @@
static constexpr const char* kPublicNativeLibrariesSystemConfig = "/system/etc/public.libraries.txt";
static constexpr const char* kPublicNativeLibrariesVendorConfig = "/vendor/etc/public.libraries.txt";
-static bool namespace_workaround_enabled(int32_t target_sdk_version) {
- return target_sdk_version <= 23;
-}
-
class LibraryNamespaces {
public:
LibraryNamespaces() : initialized_(false) { }
@@ -156,18 +152,7 @@
bool InitPublicNamespace(const char* library_path, int32_t target_sdk_version) {
std::string publicNativeLibraries = public_libraries_;
- // TODO (dimitry): This is a workaround for http://b/26436837
- // will be removed before the release.
- if (namespace_workaround_enabled(target_sdk_version)) {
- // check if libart.so is loaded.
- void* handle = dlopen("libart.so", RTLD_NOW | RTLD_NOLOAD);
- if (handle != nullptr) {
- publicNativeLibraries += ":libart.so";
- dlclose(handle);
- }
- }
- // END OF WORKAROUND
-
+ UNUSED(target_sdk_version);
// (http://b/25844435) - Some apps call dlopen from generated code (mono jited
// code is one example) unknown to linker in which case linker uses anonymous
// namespace. The second argument specifies the search path for the anonymous
diff --git a/libnetutils/Android.mk b/libnetutils/Android.mk
index ff899c0..ce7c3ba 100644
--- a/libnetutils/Android.mk
+++ b/libnetutils/Android.mk
@@ -15,6 +15,9 @@
LOCAL_CFLAGS := -Werror
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
diff --git a/include/netutils/dhcp.h b/libnetutils/include/netutils/dhcp.h
similarity index 100%
rename from include/netutils/dhcp.h
rename to libnetutils/include/netutils/dhcp.h
diff --git a/include/netutils/ifc.h b/libnetutils/include/netutils/ifc.h
similarity index 100%
rename from include/netutils/ifc.h
rename to libnetutils/include/netutils/ifc.h
diff --git a/libpackagelistparser/packagelistparser.c b/libpackagelistparser/packagelistparser.c
index 16052e2..e309027 100644
--- a/libpackagelistparser/packagelistparser.c
+++ b/libpackagelistparser/packagelistparser.c
@@ -27,7 +27,7 @@
#include <sys/limits.h>
#define LOG_TAG "packagelistparser"
-#include <utils/Log.h>
+#include <cutils/log.h>
#include <packagelistparser/packagelistparser.h>
diff --git a/libpixelflinger/codeflinger/GGLAssembler.h b/libpixelflinger/codeflinger/GGLAssembler.h
index 9db20df..ecc242a 100644
--- a/libpixelflinger/codeflinger/GGLAssembler.h
+++ b/libpixelflinger/codeflinger/GGLAssembler.h
@@ -288,6 +288,14 @@
private:
+ // GGLAssembler hides RegisterAllocator's and ARMAssemblerProxy's reset
+ // methods by providing a reset method with a different parameter set. The
+ // intent of GGLAssembler's reset method is to wrap the inherited reset
+ // methods, so make these methods private in order to prevent direct calls
+ // to these methods from clients.
+ using RegisterAllocator::reset;
+ using ARMAssemblerProxy::reset;
+
struct tex_coord_t {
reg_t s;
reg_t t;
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index 1bc1659..cfc9ae2 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -29,6 +29,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <memory>
#include <log/log.h>
#include <private/android_filesystem_config.h>
@@ -201,11 +202,11 @@
static void removeUidProcessGroups(const char *uid_path)
{
- DIR *uid = opendir(uid_path);
+ std::unique_ptr<DIR, decltype(&closedir)> uid(opendir(uid_path), closedir);
if (uid != NULL) {
struct dirent cur;
struct dirent *dir;
- while ((readdir_r(uid, &cur, &dir) == 0) && dir) {
+ while ((readdir_r(uid.get(), &cur, &dir) == 0) && dir) {
char path[PROCESSGROUP_MAX_PATH_LEN];
if (dir->d_type != DT_DIR) {
@@ -220,7 +221,6 @@
SLOGV("removing %s\n", path);
rmdir(path);
}
- closedir(uid);
}
}
@@ -228,13 +228,13 @@
{
SLOGV("removeAllProcessGroups()");
const char *cgroup_root_path = getCgroupRootPath();
- DIR *root = opendir(cgroup_root_path);
+ std::unique_ptr<DIR, decltype(&closedir)> root(opendir(cgroup_root_path), closedir);
if (root == NULL) {
SLOGE("failed to open %s: %s", cgroup_root_path, strerror(errno));
} else {
struct dirent cur;
struct dirent *dir;
- while ((readdir_r(root, &cur, &dir) == 0) && dir) {
+ while ((readdir_r(root.get(), &cur, &dir) == 0) && dir) {
char path[PROCESSGROUP_MAX_PATH_LEN];
if (dir->d_type != DT_DIR) {
@@ -249,7 +249,6 @@
SLOGV("removing %s\n", path);
rmdir(path);
}
- closedir(root);
}
}
diff --git a/libsync/sync_test.c b/libsync/sync_test.c
index ee9ea3c..9a5f7d8 100644
--- a/libsync/sync_test.c
+++ b/libsync/sync_test.c
@@ -92,7 +92,7 @@
for (j = 0; j < 2; j++) {
unsigned val = i + j * 3 + 1;
- sprintf(str, "test_fence%d-%d", i, j);
+ snprintf(str, sizeof(str), "test_fence%d-%d", i, j);
int fd = sw_sync_fence_create(sync_timeline_fd, str, val);
if (fd < 0) {
printf("can't create sync pt %d: %s", val, strerror(errno));
@@ -106,7 +106,7 @@
sync_data[3].thread_no = 3;
for (j = 0; j < 2; j++) {
- sprintf(str, "merged_fence%d", j);
+ snprintf(str, sizeof(str), "merged_fence%d", j);
sync_data[3].fd[j] = sync_merge(str, sync_data[0].fd[j], sync_data[1].fd[j]);
if (sync_data[3].fd[j] < 0) {
printf("can't merge sync pts %d and %d: %s\n",
diff --git a/libsysutils/src/SocketListener.cpp b/libsysutils/src/SocketListener.cpp
index 168899c..4d602a6 100644
--- a/libsysutils/src/SocketListener.cpp
+++ b/libsysutils/src/SocketListener.cpp
@@ -206,7 +206,7 @@
do {
alen = sizeof(ss);
- c = accept(mSock, addrp, &alen);
+ c = accept4(mSock, addrp, &alen, SOCK_CLOEXEC);
SLOGV("%s got %d from accept", mSocketName, c);
} while (c < 0 && errno == EINTR);
if (c < 0) {
@@ -214,7 +214,6 @@
sleep(1);
continue;
}
- fcntl(c, F_SETFD, FD_CLOEXEC);
pthread_mutex_lock(&mClientsLock);
mClients->push_back(new SocketClient(c, true, mUseCmdNum));
pthread_mutex_unlock(&mClientsLock);
diff --git a/libutils/ProcessCallStack.cpp b/libutils/ProcessCallStack.cpp
index cdb586d..4e87a98 100644
--- a/libutils/ProcessCallStack.cpp
+++ b/libutils/ProcessCallStack.cpp
@@ -21,6 +21,7 @@
#include <errno.h>
#include <stdio.h>
#include <string.h>
+#include <memory>
#include <utils/Log.h>
#include <utils/Errors.h>
@@ -130,11 +131,10 @@
}
void ProcessCallStack::update() {
- DIR *dp;
struct dirent *ep;
struct dirent entry;
- dp = opendir(PATH_SELF_TASK);
+ std::unique_ptr<DIR, decltype(&closedir)> dp(opendir(PATH_SELF_TASK), closedir);
if (dp == NULL) {
ALOGE("%s: Failed to update the process's call stacks: %s",
__FUNCTION__, strerror(errno));
@@ -159,7 +159,7 @@
* - Read every file in directory => get every tid
*/
int code;
- while ((code = readdir_r(dp, &entry, &ep)) == 0 && ep != NULL) {
+ while ((code = readdir_r(dp.get(), &entry, &ep)) == 0 && ep != NULL) {
pid_t tid = -1;
sscanf(ep->d_name, "%d", &tid);
@@ -198,8 +198,6 @@
ALOGE("%s: Failed to readdir from %s: %s",
__FUNCTION__, PATH_SELF_TASK, strerror(code));
}
-
- closedir(dp);
}
void ProcessCallStack::log(const char* logtag, android_LogPriority priority,
diff --git a/libutils/RefBase.cpp b/libutils/RefBase.cpp
index 02907ad..ea1e4db 100644
--- a/libutils/RefBase.cpp
+++ b/libutils/RefBase.cpp
@@ -190,17 +190,22 @@
{
Mutex::Autolock _l(mMutex);
char buf[128];
- sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this);
+ snprintf(buf, sizeof(buf),
+ "Strong references on RefBase %p (weakref_type %p):\n",
+ mBase, this);
text.append(buf);
printRefsLocked(&text, mStrongRefs);
- sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this);
+ snprintf(buf, sizeof(buf),
+ "Weak references on RefBase %p (weakref_type %p):\n",
+ mBase, this);
text.append(buf);
printRefsLocked(&text, mWeakRefs);
}
{
char name[100];
- snprintf(name, 100, DEBUG_REFS_CALLSTACK_PATH "/%p.stack", this);
+ snprintf(name, sizeof(name), DEBUG_REFS_CALLSTACK_PATH "/%p.stack",
+ this);
int rc = open(name, O_RDWR | O_CREAT | O_APPEND, 644);
if (rc >= 0) {
write(rc, text.string(), text.length());
@@ -293,8 +298,8 @@
char buf[128];
while (refs) {
char inc = refs->ref >= 0 ? '+' : '-';
- sprintf(buf, "\t%c ID %p (ref %d):\n",
- inc, refs->id, refs->ref);
+ snprintf(buf, sizeof(buf), "\t%c ID %p (ref %d):\n",
+ inc, refs->id, refs->ref);
out->append(buf);
#if DEBUG_REFS_CALLSTACK_ENABLED
out->append(refs->stack.toString("\t\t"));
diff --git a/libutils/String16.cpp b/libutils/String16.cpp
index 6a5273f..87eda1b 100644
--- a/libutils/String16.cpp
+++ b/libutils/String16.cpp
@@ -18,7 +18,6 @@
#include <utils/Log.h>
#include <utils/Unicode.h>
-#include <utils/String8.h>
#include <utils/threads.h>
#include <memory.h>
@@ -77,7 +76,7 @@
//printf("Created UTF-16 string from UTF-8 \"%s\":", in);
//printHexData(1, str, buf->size(), 16, 1);
//printf("\n");
-
+
return u16str;
}
@@ -127,7 +126,7 @@
mString = str;
return;
}
-
+
mString = getEmptyString();
}
@@ -142,7 +141,7 @@
mString = str;
return;
}
-
+
mString = getEmptyString();
}
@@ -228,7 +227,7 @@
} else if (otherLen == 0) {
return NO_ERROR;
}
-
+
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
->editResize((myLen+otherLen+1)*sizeof(char16_t));
if (buf) {
@@ -249,7 +248,7 @@
} else if (otherLen == 0) {
return NO_ERROR;
}
-
+
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
->editResize((myLen+otherLen+1)*sizeof(char16_t));
if (buf) {
diff --git a/libutils/String8.cpp b/libutils/String8.cpp
index 771d312..ad45282 100644
--- a/libutils/String8.cpp
+++ b/libutils/String8.cpp
@@ -362,7 +362,7 @@
status_t String8::real_append(const char* other, size_t otherLen)
{
const size_t myLen = bytes();
-
+
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
->editResize(myLen+otherLen+1);
if (buf) {
diff --git a/libutils/SystemClock.cpp b/libutils/SystemClock.cpp
index 1fca2b2..c5ae327 100644
--- a/libutils/SystemClock.cpp
+++ b/libutils/SystemClock.cpp
@@ -56,66 +56,12 @@
return nanoseconds_to_milliseconds(elapsedRealtimeNano());
}
-#define METHOD_CLOCK_GETTIME 0
-#define METHOD_IOCTL 1
-#define METHOD_SYSTEMTIME 2
-
-/*
- * To debug/verify the timestamps returned by the kernel, change
- * DEBUG_TIMESTAMP to 1 and call the timestamp routine from a single thread
- * in the test program. b/10899829
- */
-#define DEBUG_TIMESTAMP 0
-
-#if DEBUG_TIMESTAMP && defined(__arm__)
-static inline void checkTimeStamps(int64_t timestamp,
- int64_t volatile *prevTimestampPtr,
- int volatile *prevMethodPtr,
- int curMethod)
-{
- /*
- * Disable the check for SDK since the prebuilt toolchain doesn't contain
- * gettid, and int64_t is different on the ARM platform
- * (ie long vs long long).
- */
- int64_t prevTimestamp = *prevTimestampPtr;
- int prevMethod = *prevMethodPtr;
-
- if (timestamp < prevTimestamp) {
- static const char *gettime_method_names[] = {
- "clock_gettime",
- "ioctl",
- "systemTime",
- };
-
- ALOGW("time going backwards: prev %lld(%s) vs now %lld(%s), tid=%d",
- prevTimestamp, gettime_method_names[prevMethod],
- timestamp, gettime_method_names[curMethod],
- gettid());
- }
- // NOTE - not atomic and may generate spurious warnings if the 64-bit
- // write is interrupted or not observed as a whole.
- *prevTimestampPtr = timestamp;
- *prevMethodPtr = curMethod;
-}
-#else
-#define checkTimeStamps(timestamp, prevTimestampPtr, prevMethodPtr, curMethod)
-#endif
-
/*
* native public static long elapsedRealtimeNano();
*/
int64_t elapsedRealtimeNano()
{
#if defined(__ANDROID__)
- struct timespec ts;
- int result;
- int64_t timestamp;
-#if DEBUG_TIMESTAMP
- static volatile int64_t prevTimestamp;
- static volatile int prevMethod;
-#endif
-
static int s_fd = -1;
if (s_fd == -1) {
@@ -125,31 +71,20 @@
}
}
- result = ioctl(s_fd,
- ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
-
- if (result == 0) {
- timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
- checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_IOCTL);
- return timestamp;
+ struct timespec ts;
+ if (ioctl(s_fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts) == 0) {
+ return seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
}
// /dev/alarm doesn't exist, fallback to CLOCK_BOOTTIME
- result = clock_gettime(CLOCK_BOOTTIME, &ts);
- if (result == 0) {
- timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
- checkTimeStamps(timestamp, &prevTimestamp, &prevMethod,
- METHOD_CLOCK_GETTIME);
- return timestamp;
+ if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0) {
+ return seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
}
// XXX: there was an error, probably because the driver didn't
// exist ... this should return
// a real error, like an exception!
- timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
- checkTimeStamps(timestamp, &prevTimestamp, &prevMethod,
- METHOD_SYSTEMTIME);
- return timestamp;
+ return systemTime(SYSTEM_TIME_MONOTONIC);
#else
return systemTime(SYSTEM_TIME_MONOTONIC);
#endif
diff --git a/libutils/tests/Vector_test.cpp b/libutils/tests/Vector_test.cpp
index d9b32f9..24ecf86 100644
--- a/libutils/tests/Vector_test.cpp
+++ b/libutils/tests/Vector_test.cpp
@@ -89,9 +89,9 @@
vector.add(4);
vector.setCapacity(8);
- ASSERT_EQ(8, vector.capacity());
+ ASSERT_EQ(8U, vector.capacity());
vector.setCapacity(2);
- ASSERT_EQ(8, vector.capacity());
+ ASSERT_EQ(8U, vector.capacity());
}
// NOTE: All of the tests below are useless because of the "TODO" above.
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 37f4f4f..52f49cc 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -27,6 +27,7 @@
#include <android-base/file.h>
#include <android-base/strings.h>
+#include <cutils/properties.h>
#include <cutils/sched_policy.h>
#include <cutils/sockets.h>
#include <log/event_tag_map.h>
@@ -35,7 +36,7 @@
#include <log/logd.h>
#include <log/logger.h>
#include <log/logprint.h>
-#include <utils/threads.h>
+#include <system/thread_defs.h>
#include <pcrecpp.h>
@@ -278,66 +279,68 @@
fprintf(stderr,"Usage: %s [options] [filterspecs]\n", cmd);
fprintf(stderr, "options include:\n"
- " -s Set default filter to silent.\n"
- " Like specifying filterspec '*:S'\n"
- " -f <filename> Log to file. Default is stdout\n"
- " --file=<filename>\n"
- " -r <kbytes> Rotate log every kbytes. Requires -f\n"
- " --rotate-kbytes=<kbytes>\n"
- " -n <count> Sets max number of rotated logs to <count>, default 4\n"
- " --rotate-count=<count>\n"
- " -v <format> Sets the log print format, where <format> is:\n"
- " --format=<format>\n"
- " brief color epoch long monotonic printable process raw\n"
- " tag thread threadtime time uid usec UTC year zone\n\n"
- " -D print dividers between each log buffer\n"
- " --dividers\n"
- " -c clear (flush) the entire log and exit\n"
- " --clear\n"
- " -d dump the log and then exit (don't block)\n"
- " -e <expr> only print lines where the log message matches <expr>\n"
- " --regex <expr> where <expr> is a regular expression\n"
- " -m <count> quit after printing <count> lines. This is meant to be\n"
- " --max-count=<count> paired with --regex, but will work on its own.\n"
- " --print paired with --regex and --max-count to let content bypass\n"
+ " -s Set default filter to silent. Equivalent to filterspec '*:S'\n"
+ " -f <file>, --file=<file> Log to file. Default is stdout\n"
+ " -r <kbytes>, --rotate-kbytes=<kbytes> Rotate log every kbytes. Requires -f\n"
+ " option. Permits property expansion.\n"
+ " -n <count>, --rotate-count=<count> Sets max number of rotated logs to\n"
+ " <count>, default 4. Permits property expansion.\n"
+ " -v <format>, --format=<format>\n"
+ " Sets the log print format, where <format> is:\n"
+ " brief color epoch long monotonic printable process raw\n"
+ " tag thread threadtime time uid usec UTC year zone\n"
+ " -D, --dividers Print dividers between each log buffer\n"
+ " -c, --clear Clear (flush) the entire log and exit\n"
+ " -d Dump the log and then exit (don't block)\n"
+ " -e <expr>, --regex=<expr>\n"
+ " Only print lines where the log message matches <expr>\n"
+ " where <expr> is a regular expression\n"
+ // Leave --head undocumented as alias for -m
+ " -m <count>, --max-count=<count>\n"
+ " Quit after printing <count> lines. This is meant to be\n"
+ " paired with --regex, but will work on its own.\n"
+ " --print Paired with --regex and --max-count to let content bypass\n"
" regex filter but still stop at number of matches.\n"
- " -t <count> print only the most recent <count> lines (implies -d)\n"
- " -t '<time>' print most recent lines since specified time (implies -d)\n"
- " -T <count> print only the most recent <count> lines (does not imply -d)\n"
- " -T '<time>' print most recent lines since specified time (not imply -d)\n"
+ // Leave --tail undocumented as alias for -t
+ " -t <count> Print only the most recent <count> lines (implies -d)\n"
+ " -t '<time>' Print most recent lines since specified time (implies -d)\n"
+ " -T <count> Print only the most recent <count> lines (does not imply -d)\n"
+ " -T '<time>' Print most recent lines since specified time (not imply -d)\n"
" count is pure numerical, time is 'MM-DD hh:mm:ss.mmm...'\n"
" 'YYYY-MM-DD hh:mm:ss.mmm...' or 'sssss.mmm...' format\n"
- " -g get the size of the log's ring buffer and exit\n"
- " --buffer-size\n"
- " -G <size> set size of log ring buffer, may suffix with K or M.\n"
- " --buffer-size=<size>\n"
- " -L dump logs from prior to last reboot\n"
- " --last\n"
+ " -g, --buffer-size Get the size of the ring buffer.\n"
+ " -G <size>, --buffer-size=<size>\n"
+ " Set size of log ring buffer, may suffix with K or M.\n"
+ " -L, -last Dump logs from prior to last reboot\n"
// Leave security (Device Owner only installations) and
// kernel (userdebug and eng) buffers undocumented.
- " -b <buffer> Request alternate ring buffer, 'main', 'system', 'radio',\n"
- " --buffer=<buffer> 'events', 'crash', 'default' or 'all'. Multiple -b\n"
- " parameters are allowed and results are interleaved. The\n"
- " default is -b main -b system -b crash.\n"
- " -B output the log in binary.\n"
- " --binary\n"
- " -S output statistics.\n"
- " --statistics\n"
- " -p print prune white and ~black list. Service is specified as\n"
- " --prune UID, UID/PID or /PID. Weighed for quicker pruning if prefix\n"
+ " -b <buffer>, --buffer=<buffer> Request alternate ring buffer, 'main',\n"
+ " 'system', 'radio', 'events', 'crash', 'default' or 'all'.\n"
+ " Multiple -b parameters or comma separated list of buffers are\n"
+ " allowed. Buffers interleaved. Default -b main,system,crash.\n"
+ " Permits property expansion.\n"
+ " -B, --binary Output the log in binary.\n"
+ " -S, --statistics Output statistics.\n"
+ " -p, --prune Print prune white and ~black list. Service is specified as\n"
+ " UID, UID/PID or /PID. Weighed for quicker pruning if prefix\n"
" with ~, otherwise weighed for longevity if unadorned. All\n"
" other pruning activity is oldest first. Special case ~!\n"
" represents an automatic quicker pruning for the noisiest\n"
" UID as determined by the current statistics.\n"
- " -P '<list> ...' set prune white and ~black list, using same format as\n"
- " --prune='<list> ...' printed above. Must be quoted.\n"
+ " -P '<list> ...', --prune='<list> ...'\n"
+ " Set prune white and ~black list, using same format as\n"
+ " listed above. Must be quoted.\n"
" --pid=<pid> Only prints logs from the given pid.\n"
- // Check ANDROID_LOG_WRAP_DEFAULT_TIMEOUT value
+ // Check ANDROID_LOG_WRAP_DEFAULT_TIMEOUT value for match to 2 hours
" --wrap Sleep for 2 hours or when buffer about to wrap whichever\n"
" comes first. Improves efficiency of polling by providing\n"
" an about-to-wrap wakeup.\n");
- fprintf(stderr,"\nfilterspecs are a series of \n"
+ fprintf(stderr,"\nProperty expansion where available, may need to be single quoted to prevent\n"
+ "shell expansion:\n"
+ " ${key} - Expand string with property value associated with key\n"
+ " ${key:-default} - Expand, if property key value clear, use default\n"
+ "\nfilterspecs are a series of \n"
" <tag>[:priority]\n\n"
"where <tag> is a log component tag (or * for all) and priority is:\n"
" V Verbose (default for <tag>)\n"
@@ -394,7 +397,7 @@
}
/*String to unsigned int, returns -1 if it fails*/
-static bool getSizeTArg(char *ptr, size_t *val, size_t min = 0,
+static bool getSizeTArg(const char *ptr, size_t *val, size_t min = 0,
size_t max = SIZE_MAX)
{
if (!ptr) {
@@ -535,6 +538,49 @@
return retval;
}
+// Expand multiple flat property references ${<tag>:-default} or ${tag}.
+//
+// ToDo: Do we permit nesting?
+// ${persist.logcat.something:-${ro.logcat.something:-maybesomething}}
+// For now this will result in a syntax error for caller and is acceptable.
+//
+std::string expand(const char *str)
+{
+ std::string retval(str);
+
+ // Caller has no use for ${, } or :- as literals so no use for escape
+ // character. Result expectations are a number or a string, with validity
+ // checking for both in caller. Recursive expansion or other syntax errors
+ // will result in content caller can not obviously tolerate, error must
+ // report substring if applicable, expanded and original content (if
+ // different) so that it will be clear to user what they did wrong.
+ for (size_t pos; (pos = retval.find("${")) != std::string::npos; ) {
+ size_t epos = retval.find("}", pos + 2);
+ if (epos == std::string::npos) {
+ break; // Caller will error out, showing this unexpanded.
+ }
+ size_t def = retval.find(":-", pos + 2);
+ if (def >= epos) {
+ def = std::string::npos;
+ }
+ std::string default_value("");
+ std::string key;
+ if (def == std::string::npos) {
+ key = retval.substr(pos + 2, epos - (pos + 2));
+ } else {
+ key = retval.substr(pos + 2, def - (pos + 2));
+ default_value = retval.substr(def + 2, epos - (def + 2));
+ }
+ char value[PROPERTY_VALUE_MAX];
+ property_get(key.c_str(), value, default_value.c_str());
+ // Caller will error out, syntactically empty content at this point
+ // will not be tolerated as expected.
+ retval.replace(pos, epos - pos + 1, value);
+ }
+
+ return retval;
+}
+
} /* namespace android */
@@ -765,111 +811,75 @@
break;
case 'b': {
- if (strcmp(optarg, "default") == 0) {
- for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
- switch (i) {
- case LOG_ID_SECURITY:
- case LOG_ID_EVENTS:
- continue;
- case LOG_ID_MAIN:
- case LOG_ID_SYSTEM:
- case LOG_ID_CRASH:
- break;
- default:
- continue;
- }
+ unsigned idMask = 0;
+ std::string expanded = expand(optarg);
+ std::istringstream copy(expanded);
+ std::string token;
+ // wish for strtok and ",:; \t\n\r\f" for hidden flexibility
+ while (std::getline(copy, token, ',')) { // settle for ","
+ if (token.compare("default") == 0) {
+ idMask |= (1 << LOG_ID_MAIN) |
+ (1 << LOG_ID_SYSTEM) |
+ (1 << LOG_ID_CRASH);
+ } else if (token.compare("all") == 0) {
+ idMask = (unsigned)-1;
+ } else {
+ log_id_t log_id = android_name_to_log_id(token.c_str());
+ const char *name = android_log_id_to_name(log_id);
- const char *name = android_log_id_to_name((log_id_t)i);
- log_id_t log_id = android_name_to_log_id(name);
-
- if (log_id != (log_id_t)i) {
- continue;
- }
-
- bool found = false;
- for (dev = devices; dev; dev = dev->next) {
- if (!strcmp(optarg, dev->device)) {
- found = true;
- break;
+ if (token.compare(name) != 0) {
+ bool strDifferent = expanded.compare(token);
+ if (expanded.compare(optarg)) {
+ expanded += " expanded from ";
+ expanded += optarg;
}
- if (!dev->next) {
- break;
+ if (strDifferent) {
+ expanded = token + " within " + expanded;
}
+ logcat_panic(true, "unknown buffer -b %s\n",
+ expanded.c_str());
}
- if (found) {
- break;
- }
-
- log_device_t* d = new log_device_t(name, false);
-
- if (dev) {
- dev->next = d;
- dev = d;
- } else {
- devices = dev = d;
- }
- g_devCount++;
+ idMask |= (1 << log_id);
}
- break;
}
- if (strcmp(optarg, "all") == 0) {
- for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
- const char *name = android_log_id_to_name((log_id_t)i);
- log_id_t log_id = android_name_to_log_id(name);
+ for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
+ const char *name = android_log_id_to_name((log_id_t)i);
+ log_id_t log_id = android_name_to_log_id(name);
- if (log_id != (log_id_t)i) {
- continue;
- }
+ if (log_id != (log_id_t)i) {
+ continue;
+ }
+ if ((idMask & (1 << i)) == 0) {
+ continue;
+ }
- bool found = false;
- for (dev = devices; dev; dev = dev->next) {
- if (!strcmp(optarg, dev->device)) {
- found = true;
- break;
- }
- if (!dev->next) {
- break;
- }
- }
- if (found) {
+ bool found = false;
+ for (dev = devices; dev; dev = dev->next) {
+ if (!strcmp(name, dev->device)) {
+ found = true;
break;
}
-
- bool binary = !strcmp(name, "events") ||
- !strcmp(name, "security");
- log_device_t* d = new log_device_t(name, binary);
-
- if (dev) {
- dev->next = d;
- dev = d;
- } else {
- devices = dev = d;
- }
- g_devCount++;
- }
- break;
- }
-
- bool binary = !(strcmp(optarg, "events") &&
- strcmp(optarg, "security"));
-
- if (devices) {
- dev = devices;
- while (dev->next) {
- if (!strcmp(optarg, dev->device)) {
- dev = NULL;
+ if (!dev->next) {
break;
}
- dev = dev->next;
}
+ if (found) {
+ continue;
+ }
+
+ bool binary = !strcmp(name, "events") ||
+ !strcmp(name, "security");
+ log_device_t* d = new log_device_t(name, binary);
+
if (dev) {
- dev->next = new log_device_t(optarg, binary);
+ dev->next = d;
+ dev = d;
+ } else {
+ devices = dev = d;
}
- } else {
- devices = new log_device_t(optarg, binary);
+ g_devCount++;
}
- g_devCount++;
}
break;
@@ -885,22 +895,36 @@
g_outputFileName = optarg;
break;
- case 'r':
- if (!getSizeTArg(optarg, &g_logRotateSizeKBytes, 1)) {
- logcat_panic(true, "Invalid parameter %s to -r\n", optarg);
+ case 'r': {
+ std::string expanded = expand(optarg);
+ if (!getSizeTArg(expanded.c_str(), &g_logRotateSizeKBytes, 1)) {
+ if (expanded.compare(optarg)) {
+ expanded += " expanded from ";
+ expanded += optarg;
+ }
+ logcat_panic(true, "Invalid parameter -r %s\n",
+ expanded.c_str());
}
+ }
break;
- case 'n':
- if (!getSizeTArg(optarg, &g_maxRotatedLogs, 1)) {
- logcat_panic(true, "Invalid parameter %s to -n\n", optarg);
+ case 'n': {
+ std::string expanded = expand(optarg);
+ if (!getSizeTArg(expanded.c_str(), &g_maxRotatedLogs, 1)) {
+ if (expanded.compare(optarg)) {
+ expanded += " expanded from ";
+ expanded += optarg;
+ }
+ logcat_panic(true, "Invalid parameter -n %s\n",
+ expanded.c_str());
}
+ }
break;
case 'v':
err = setLogFormat (optarg);
if (err < 0) {
- logcat_panic(true, "Invalid parameter %s to -v\n", optarg);
+ logcat_panic(true, "Invalid parameter -v %s\n", optarg);
}
hasSetLogFormat |= err;
break;
diff --git a/logcat/logcatd.rc b/logcat/logcatd.rc
index cf0e0d2..70d1dd4 100644
--- a/logcat/logcatd.rc
+++ b/logcat/logcatd.rc
@@ -2,10 +2,10 @@
# all exec/services are called with umask(077), so no gain beyond 0700
mkdir /data/misc/logd 0700 logd log
# logd for write to /data/misc/logd, log group for read from pstore (-L)
- exec - logd log -- /system/bin/logcat -L -b all -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r 1024 -n 256
+ exec - logd log -- /system/bin/logcat -L -b ${persist.logd.logpersistd.buffer:-all} -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r 1024 -n ${persist.logd.logpersistd.size:-256}
start logcatd
-service logcatd /system/bin/logcat -b all -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r 1024 -n 256
+service logcatd /system/bin/logcat -b ${persist.logd.logpersistd.buffer:-all} -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r 1024 -n ${persist.logd.logpersistd.size:-256}
class late_start
disabled
# logd for write to /data/misc/logd, log group for read from log daemon
diff --git a/logcat/logpersist b/logcat/logpersist
index dab466d..e448456 100755
--- a/logcat/logpersist
+++ b/logcat/logpersist
@@ -1,42 +1,140 @@
#! /system/bin/sh
-# logpersist cat start and stop handlers
+# logpersist cat, start and stop handlers
progname="${0##*/}"
-case `getprop ro.build.type` in
-userdebug|eng) ;;
+case `getprop ro.debuggable` in
+1) ;;
*) echo "${progname} - Permission denied"
exit 1
;;
esac
+
data=/data/misc/logd
property=persist.logd.logpersistd
service=logcatd
-if [ X"${1}" = X"-h" -o X"${1}" = X"--help" ]; then
- echo "${progname%.*}.cat - dump current ${service%d} logs"
- echo "${progname%.*}.start - start ${service} service"
- echo "${progname%.*}.stop [--clear] - stop ${service} service"
- exit 0
+size_default=256
+buffer_default=all
+args="${@}"
+
+size=${size_default}
+buffer=${buffer_default}
+clear=false
+while [ ${#} -gt 0 ]; do
+ case ${1} in
+ -c|--clear) clear=true ;;
+ --size=*) size="${1#--size=}" ;;
+ --rotate-count=*) size="${1#--rotate-count=}" ;;
+ -n|--size|--rotate-count) size="${2}" ; shift ;;
+ --buffer=*) buffer="${1#--buffer=}" ;;
+ -b|--buffer) buffer="${2}" ; shift ;;
+ -h|--help|*)
+ LEAD_SPACE_="`echo ${progname%.*} | tr '[ -~]' ' '`"
+ echo "${progname%.*}.cat - dump current ${service%d} logs"
+ echo "${progname%.*}.start [--size=<size_in_kb>] [--buffer=<buffers>] [--clear]"
+ echo "${LEAD_SPACE_} - start ${service} service"
+ echo "${progname%.*}.stop [--clear] - stop ${service} service"
+ case ${1} in
+ -h|--help) exit 0 ;;
+ *) echo ERROR: bad argument ${@} >&2 ; exit 1 ;;
+ esac
+ ;;
+ esac
+ shift
+done
+
+if [ -z "${size}" -o "${size_default}" = "${size}" ]; then
+ unset size
fi
+if [ -n "${size}" ] &&
+ ! ( [ 0 -lt "${size}" ] && [ 2048 -ge "${size}" ] ) >/dev/null 2>&1; then
+ echo ERROR: Invalid --size ${size} >&2
+ exit 1
+fi
+if [ -z "${buffer}" -o "${buffer_default}" = "${buffer}" ]; then
+ unset buffer
+fi
+if [ -n "${buffer}" ] && ! logcat -b ${buffer} -g >/dev/null 2>&1; then
+ echo ERROR: Invalid --buffer ${buffer} >&2
+ exit 1
+fi
+
case ${progname} in
*.cat)
- su 1036 ls "${data}" |
+ if [ -n "${size}${buffer}" -o "true" = "${clear}" ]; then
+ echo WARNING: Can not use --clear, --size or --buffer with ${progname%.*}.cat >&2
+ fi
+ su logd ls "${data}" |
tr -d '\r' |
sort -ru |
sed "s#^#${data}/#" |
- su 1036 xargs cat
+ su logd xargs cat
;;
*.start)
- su 0 setprop ${property} ${service}
+ current_buffer="`getprop ${property}.buffer`"
+ current_size="`getprop ${property}.size`"
+ if [ "${service}" = "`getprop ${property}`" ]; then
+ if [ "true" = "${clear}" ]; then
+ su root stop ${service}
+ su root setprop ${property} ""
+ # 20ms done, guarantees content stop before rm
+ sleep 1
+ elif [ "${buffer}|${size}" != "${current_buffer}|${current_size}" ]; then
+ echo "ERROR: Changing existing collection parameters from" >&2
+ if [ "${buffer}" != "${current_buffer}" ]; then
+ a=${current_buffer}
+ b=${buffer}
+ if [ -z "${a}" ]; then a="${default_buffer}"; fi
+ if [ -z "${b}" ]; then b="${default_buffer}"; fi
+ echo " --buffer ${a} to ${b}" >&2
+ fi
+ if [ "${size}" != "${current_size}" ]; then
+ a=${current_size}
+ b=${size}
+ if [ -z "${a}" ]; then a="${default_size}"; fi
+ if [ -z "${b}" ]; then b="${default_size}"; fi
+ echo " --size ${a} to ${b}" >&2
+ fi
+ echo " Are you sure you want to do this?" >&2
+ echo " Suggest add --clear to erase data and restart with new settings." >&2
+ echo " To blindly override and retain data, ${progname%.*}.stop first." >&2
+ exit 1
+ fi
+ fi
+ if [ "true" = "${clear}" ]; then
+ su logd,misc rm -rf "${data}"
+ fi
+ if [ -n "${buffer}${current_buffer}" ]; then
+ su root setprop ${property}.buffer "${buffer}"
+ fi
+ if [ -n "${size}${current_size}" ]; then
+ su root setprop ${property}.size "${size}"
+ fi
+ # ${service}.rc does the heavy lifting with the following trigger
+ su root setprop ${property} ${service}
getprop ${property}
+ # 20ms done, to permit process feedback check
sleep 1
+ # also generate an error return code if not found running, bonus
ps -t | grep "${data##*/}.*${service%d}"
;;
*.stop)
- su 0 stop ${service}
- su 0 setprop ${property} ""
- [ X"${1}" != X"-c" -a X"${1}" != X"--clear" ] ||
- ( sleep 1 ; su 1036,9998 rm -rf "${data}" )
+ if [ -n "${size}${buffer}" ]; then
+ echo "WARNING: Can not use --size or --buffer with ${progname%.*}.stop" >&2
+ fi
+ su root stop ${service}
+ su root setprop ${property} ""
+ if [ -n "`getprop ${property}.buffer`" ]; then
+ su root setprop ${property}.buffer ""
+ fi
+ if [ -n "`getprop ${property}.size`" ]; then
+ su root setprop ${property}.size ""
+ fi
+ if [ "true" = "${clear}" ]; then
+ # 20ms done, guarantees content stop before rm
+ sleep 1
+ su logd,misc rm -rf "${data}"
+ fi
;;
*)
- echo "Unexpected command ${0##*/} ${@}" >&2
+ echo "ERROR: Unexpected command ${0##*/} ${args}" >&2
exit 1
esac
diff --git a/logcat/tests/Android.mk b/logcat/tests/Android.mk
index a28664e..3bf8a0b 100644
--- a/logcat/tests/Android.mk
+++ b/logcat/tests/Android.mk
@@ -56,6 +56,6 @@
LOCAL_MODULE := $(test_module_prefix)unit-tests
LOCAL_MODULE_TAGS := $(test_tags)
LOCAL_CFLAGS += $(test_c_flags)
-LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_SHARED_LIBRARIES := liblog libcutils
LOCAL_SRC_FILES := $(test_src_files)
include $(BUILD_NATIVE_TEST)
diff --git a/logcat/tests/logcat_benchmark.cpp b/logcat/tests/logcat_benchmark.cpp
index be815be..dd85164 100644
--- a/logcat/tests/logcat_benchmark.cpp
+++ b/logcat/tests/logcat_benchmark.cpp
@@ -49,7 +49,7 @@
}
}
- timestamp(const char *buffer)
+ explicit timestamp(const char *buffer)
{
init(buffer);
}
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index dfcca12..997e682 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -23,11 +23,16 @@
#include <sys/types.h>
#include <sys/wait.h>
+#include <memory>
+
+#include <cutils/properties.h>
#include <gtest/gtest.h>
#include <log/log.h>
#include <log/logger.h>
#include <log/log_read.h>
+#define BIG_BUFFER (5 * 1024)
+
// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
// non-syscall libs. Since we are only using this in the emergency of
// a signal to stuff a terminating code into the logs, we will spin rather
@@ -52,7 +57,7 @@
"logcat -b radio -b events -b system -b main -d 2>/dev/null",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int ids = 0;
int count = 0;
@@ -100,7 +105,7 @@
"logcat -v long -v year -b all -t 3 2>/dev/null",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -163,7 +168,7 @@
"logcat -v long -v America/Los_Angeles -b all -t 3 2>/dev/null",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
count = 0;
@@ -187,7 +192,7 @@
"logcat -v long -v America/Los_Angeles -v zone -b all -t 3 2>/dev/null",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -207,7 +212,7 @@
int count;
do {
- char buffer[5120];
+ char buffer[BIG_BUFFER];
snprintf(buffer, sizeof(buffer),
"logcat -v long -b radio -b events -b system -b main -t %d 2>/dev/null",
@@ -250,7 +255,7 @@
ASSERT_TRUE(NULL != (fp = popen("logcat -v long -b all -t 10 2>&1", "r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
char *last_timestamp = NULL;
char *first_timestamp = NULL;
int count = 0;
@@ -313,7 +318,7 @@
"logcat -v brief -b events -t 100 2>/dev/null",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -337,15 +342,17 @@
ASSERT_EQ(1, count);
}
-TEST(logcat, get_size) {
+int get_groups(const char *cmd) {
FILE *fp;
// NB: crash log only available in user space
- ASSERT_TRUE(NULL != (fp = popen(
- "logcat -v brief -b radio -b events -b system -b main -g 2>/dev/null",
- "r")));
+ EXPECT_TRUE(NULL != (fp = popen(cmd, "r")));
- char buffer[5120];
+ if (fp == NULL) {
+ return 0;
+ }
+
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -405,7 +412,31 @@
pclose(fp);
- ASSERT_EQ(4, count);
+ return count;
+}
+
+TEST(logcat, get_size) {
+ ASSERT_EQ(4, get_groups(
+ "logcat -v brief -b radio -b events -b system -b main -g 2>/dev/null"));
+}
+
+// duplicate test for get_size, but use comma-separated list of buffers
+TEST(logcat, multiple_buffer) {
+ ASSERT_EQ(4, get_groups(
+ "logcat -v brief -b radio,events,system,main -g 2>/dev/null"));
+}
+
+// duplicate test for get_size, but use test.logcat.buffer property
+TEST(logcat, property_expand) {
+ property_set("test.logcat.buffer", "radio,events");
+ EXPECT_EQ(4, get_groups(
+ "logcat -v brief -b 'system,${test.logcat.buffer:-bogo},main' -g 2>/dev/null"));
+ property_set("test.logcat.buffer", "");
+}
+
+TEST(logcat, bad_buffer) {
+ ASSERT_EQ(0, get_groups(
+ "logcat -v brief -b radio,events,bogo,system,main -g 2>/dev/null"));
}
static void caught_blocking(int /*signum*/)
@@ -434,7 +465,7 @@
" logcat -v brief -b events 2>&1",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -503,7 +534,7 @@
" logcat -v brief -b events -T 5 2>&1",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -566,7 +597,7 @@
FILE *fp;
EXPECT_TRUE(NULL != (fp = popen(command, "r")));
if (fp) {
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
while (fgets(buffer, sizeof(buffer), fp)) {
@@ -609,7 +640,7 @@
FILE *fp;
EXPECT_TRUE(NULL != (fp = popen(command, "r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int log_file_count = 0;
while (fgets(buffer, sizeof(buffer), fp)) {
@@ -704,8 +735,8 @@
EXPECT_FALSE(system(command));
return;
}
- DIR *dir;
- EXPECT_TRUE(NULL != (dir = opendir(tmp_out_dir)));
+ std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(tmp_out_dir), closedir);
+ EXPECT_NE(nullptr, dir);
if (!dir) {
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
EXPECT_FALSE(system(command));
@@ -713,7 +744,7 @@
}
struct dirent *entry;
unsigned count = 0;
- while ((entry = readdir(dir))) {
+ while ((entry = readdir(dir.get()))) {
if (strncmp(entry->d_name, log_filename, sizeof(log_filename) - 1)) {
continue;
}
@@ -736,7 +767,6 @@
free(line);
unlink(command);
}
- closedir(dir);
if (count > 1) {
char *brk = strpbrk(second_last_line, "\r\n");
if (!brk) {
@@ -783,7 +813,7 @@
" logcat -v brief -b events 2>&1",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -844,7 +874,7 @@
return false;
}
- char buffer[5120];
+ char buffer[BIG_BUFFER];
while (fgets(buffer, sizeof(buffer), fp)) {
char *hold = *list;
@@ -873,7 +903,7 @@
static bool set_white_black(const char *list) {
FILE *fp;
- char buffer[5120];
+ char buffer[BIG_BUFFER];
snprintf(buffer, sizeof(buffer), "logcat -P '%s' 2>&1", list ? list : "");
fp = popen(buffer, "r");
@@ -935,7 +965,7 @@
FILE *fp;
int count = 0;
- char buffer[5120];
+ char buffer[BIG_BUFFER];
snprintf(buffer, sizeof(buffer), "logcat --pid %d -d -e logcat_test_a+b", getpid());
@@ -968,7 +998,7 @@
FILE *fp;
int count = 0;
- char buffer[5120];
+ char buffer[BIG_BUFFER];
snprintf(buffer, sizeof(buffer), "logcat --pid %d -d --max-count 3", getpid());
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index 9124bfd..4eb5e83 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -164,6 +164,10 @@
}
}
+ // Note: The audit log can include untrusted strings, but those containing
+ // "a control character, unprintable character, double quote mark, or a
+ // space" are hex encoded. The space character before the search term is
+ // therefore needed to prevent denial of service. Do not remove the space.
bool permissive = strstr(str, " enforcing=0") ||
strstr(str, " permissive=1");
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 8c30f79..db65978 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -380,7 +380,7 @@
tid(tid),
padding(0) {
}
- LogBufferElementKey(uint64_t key):value(key) { }
+ explicit LogBufferElementKey(uint64_t key):value(key) { }
uint64_t getKey() { return value; }
};
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index 2b02bc1..02a4a75 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -15,8 +15,10 @@
*/
#include <fcntl.h>
+#include <pwd.h>
#include <stdio.h>
#include <string.h>
+#include <sys/types.h>
#include <unistd.h>
#include <log/logger.h>
@@ -159,14 +161,13 @@
return strdup("auditd");
}
- // Android hard coded
- const struct android_id_info *info = android_ids;
-
- for (size_t i = 0; i < android_id_count; ++i) {
- if (info->aid == uid) {
- return strdup(info->name);
+ // Android system
+ if (uid < AID_APP) {
+ // in bionic, thread safe as long as we copy the results
+ struct passwd *pwd = getpwuid(uid);
+ if (pwd) {
+ return strdup(pwd->pw_name);
}
- ++info;
}
// Parse /data/system/packages.list
@@ -179,6 +180,14 @@
return name;
}
+ // Android application
+ if (uid >= AID_APP) {
+ struct passwd *pwd = getpwuid(uid);
+ if (pwd) {
+ return strdup(pwd->pw_name);
+ }
+ }
+
// report uid -> pid(s) -> pidToName if unique
for(pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end(); ++it) {
const PidEntry &entry = it->second;
diff --git a/logd/LogUtils.h b/logd/LogUtils.h
index fd4800e..aa4b6e1 100644
--- a/logd/LogUtils.h
+++ b/logd/LogUtils.h
@@ -17,6 +17,7 @@
#ifndef _LOGD_LOG_UTILS_H__
#define _LOGD_LOG_UTILS_H__
+#include <sys/cdefs.h>
#include <sys/types.h>
#include <log/log.h>
@@ -29,6 +30,7 @@
// Furnished in main.cpp. Caller must own and free returned value
char *uidToName(uid_t uid);
+void prdebug(const char *fmt, ...) __printflike(1, 2);
// Furnished in LogStatistics.cpp. Caller must own and free returned value
char *pidToName(pid_t pid);
diff --git a/logd/README.property b/logd/README.property
index 6c84b25..4bc5541 100644
--- a/logd/README.property
+++ b/logd/README.property
@@ -7,7 +7,7 @@
ro.device_owner bool false Override persist.logd.security to false
ro.logd.kernel bool+ svelte+ Enable klogd daemon
ro.logd.statistics bool+ svelte+ Enable logcat -S statistics.
-ro.build.type string if user, logd.statistics &
+ro.debuggable number if not "1", logd.statistics &
ro.logd.kernel default false.
persist.logd.logpersistd string Enable logpersist daemon, "logcatd"
turns on logcat -f in logd context
@@ -45,10 +45,10 @@
NB:
- bool+ - "true", "false" and comma separated list of "eng" (forced false if
- ro.build.type is "user") or "svelte" (forced false if ro.config.low_ram is
+ ro.debuggable is not "1") or "svelte" (forced false if ro.config.low_ram is
true).
- svelte - see ro.config.low_ram for details.
-- svelte+ - see ro.config.low_ram and ro.build.type for details.
+- svelte+ - see ro.config.low_ram and ro.debuggable for details.
- ro - <base property> temporary override, ro.<base property> platform default.
- persist - <base property> override, persist.<base property> platform default.
- build - VERBOSE for native, DEBUG for jvm isLoggable, or developer option.
diff --git a/logd/main.cpp b/logd/main.cpp
index 11c9372..3095f7f 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -202,8 +202,8 @@
return false;
}
if (flag & BOOL_DEFAULT_FLAG_ENG) {
- property_get("ro.build.type", property, "");
- if (!strcmp(property, "user")) {
+ property_get("ro.debuggable", property, "");
+ if (strcmp(property, "1")) {
return false;
}
}
@@ -211,10 +211,32 @@
return (flag & BOOL_DEFAULT_FLAG_TRUE_FALSE) != BOOL_DEFAULT_FALSE;
}
-// Remove the static, and use this variable
-// globally for debugging if necessary. eg:
-// write(fdDmesg, "I am here\n", 10);
static int fdDmesg = -1;
+void inline android::prdebug(const char *fmt, ...) {
+ if (fdDmesg < 0) {
+ return;
+ }
+
+ static const char message[] = {
+ KMSG_PRIORITY(LOG_DEBUG), 'l', 'o', 'g', 'd', ':', ' '
+ };
+ char buffer[256];
+ memcpy(buffer, message, sizeof(message));
+
+ va_list ap;
+ va_start(ap, fmt);
+ int n = vsnprintf(buffer + sizeof(message),
+ sizeof(buffer) - sizeof(message), fmt, ap);
+ va_end(ap);
+ if (n > 0) {
+ buffer[sizeof(buffer) - 1] = '\0';
+ if (!strchr(buffer, '\n')) {
+ buffer[sizeof(buffer) - 2] = '\0';
+ strlcat(buffer, "\n", sizeof(buffer));
+ }
+ write(fdDmesg, buffer, strlen(buffer));
+ }
+}
static sem_t uidName;
static uid_t uid;
diff --git a/logwrapper/logwrap.c b/logwrapper/logwrap.c
index 28d6de7..ccbe0bf 100644
--- a/logwrapper/logwrap.c
+++ b/logwrapper/logwrap.c
@@ -408,7 +408,7 @@
if (poll_fds[0].revents & POLLHUP) {
int ret;
- ret = waitpid(pid, &status, WNOHANG);
+ ret = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
if (ret < 0) {
rc = errno;
ALOG(LOG_ERROR, "logwrap", "waitpid failed with %s\n", strerror(errno));
diff --git a/metricsd/.clang-format b/metricsd/.clang-format
deleted file mode 100644
index c98efc2..0000000
--- a/metricsd/.clang-format
+++ /dev/null
@@ -1,10 +0,0 @@
-BasedOnStyle: Google
-AllowShortFunctionsOnASingleLine: Inline
-AllowShortIfStatementsOnASingleLine: false
-AllowShortLoopsOnASingleLine: false
-BinPackArguments: false
-BinPackParameters: false
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-PointerAlignment: Left
-TabWidth: 2
diff --git a/metricsd/.clang-format b/metricsd/.clang-format
new file mode 120000
index 0000000..f9066d4
--- /dev/null
+++ b/metricsd/.clang-format
@@ -0,0 +1 @@
+../../../build/tools/brillo-clang-format
\ No newline at end of file
diff --git a/metricsd/timer_test.cc b/metricsd/timer_test.cc
index 7a67e11..cfbcd8a 100644
--- a/metricsd/timer_test.cc
+++ b/metricsd/timer_test.cc
@@ -69,7 +69,7 @@
EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
.WillOnce(Return(stime))
.WillOnce(Return(etime));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
ASSERT_TRUE(timer_.Start());
ASSERT_TRUE(timer_.start_time_ == stime);
ASSERT_TRUE(timer_.HasStarted());
@@ -88,7 +88,7 @@
EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
.WillOnce(Return(stime))
.WillOnce(Return(etime));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
timer_.Start();
base::TimeTicks buffer = timer_.start_time_;
timer_.Start();
@@ -98,7 +98,7 @@
TEST_F(TimerTest, Reset) {
EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
.WillOnce(Return(stime));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
timer_.Start();
ASSERT_TRUE(timer_.Reset());
ASSERT_FALSE(timer_.HasStarted());
@@ -110,7 +110,7 @@
.WillOnce(Return(etime))
.WillOnce(Return(stime2))
.WillOnce(Return(etime2));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
ASSERT_TRUE(timer_.Start());
ASSERT_TRUE(timer_.Stop());
ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta1MSec);
@@ -130,7 +130,7 @@
EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
.WillOnce(Return(stime))
.WillOnce(Return(etime));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
ASSERT_FALSE(timer_.Stop());
// Now we try it again, but after a valid start/stop.
timer_.Start();
@@ -152,7 +152,7 @@
.WillOnce(Return(etime2))
.WillOnce(Return(stime3))
.WillOnce(Return(etime3));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
ASSERT_TRUE(timer_.Pause()); // Starts timer paused.
ASSERT_TRUE(timer_.start_time_ == stime);
ASSERT_TRUE(timer_.HasStarted());
@@ -181,7 +181,7 @@
.WillOnce(Return(stime2))
.WillOnce(Return(etime2))
.WillOnce(Return(stime3));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
ASSERT_TRUE(timer_.Resume());
ASSERT_TRUE(timer_.start_time_ == stime);
ASSERT_TRUE(timer_.HasStarted());
@@ -208,7 +208,7 @@
EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
.WillOnce(Return(stime))
.WillOnce(Return(etime));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
ASSERT_TRUE(timer_.Start());
ASSERT_TRUE(timer_.start_time_ == stime);
ASSERT_TRUE(timer_.HasStarted());
@@ -230,7 +230,7 @@
EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
.WillOnce(Return(stime))
.WillOnce(Return(etime));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
ASSERT_TRUE(timer_.Start());
ASSERT_TRUE(timer_.start_time_ == stime);
ASSERT_TRUE(timer_.HasStarted());
@@ -257,7 +257,7 @@
.WillOnce(Return(etime))
.WillOnce(Return(stime2))
.WillOnce(Return(etime2));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
ASSERT_TRUE(timer_.Start());
ASSERT_TRUE(timer_.start_time_ == stime);
ASSERT_TRUE(timer_.HasStarted());
@@ -284,7 +284,7 @@
TEST_F(TimerTest, PauseStop) {
EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
.WillOnce(Return(stime));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
ASSERT_TRUE(timer_.Pause());
ASSERT_TRUE(timer_.start_time_ == stime);
ASSERT_TRUE(timer_.HasStarted());
@@ -304,7 +304,7 @@
.WillOnce(Return(stime))
.WillOnce(Return(stime2))
.WillOnce(Return(etime2));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
ASSERT_TRUE(timer_.Pause());
ASSERT_TRUE(timer_.start_time_ == stime);
ASSERT_TRUE(timer_.HasStarted());
@@ -328,7 +328,7 @@
.WillOnce(Return(stime2))
.WillOnce(Return(stime3))
.WillOnce(Return(etime3));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
ASSERT_TRUE(timer_.Start());
ASSERT_TRUE(timer_.start_time_ == stime);
ASSERT_TRUE(timer_.HasStarted());
@@ -373,7 +373,7 @@
.WillOnce(Return(etime2))
.WillOnce(Return(stime3))
.WillOnce(Return(etime3));
- timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
ASSERT_TRUE(timer_.Start());
ASSERT_TRUE(timer_.start_time_ == stime);
ASSERT_TRUE(timer_.HasStarted());
@@ -444,7 +444,7 @@
EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
.WillOnce(Return(stime))
.WillOnce(Return(etime));
- timer_reporter_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+ timer_reporter_.clock_wrapper_ = std::move(clock_wrapper_mock_);
EXPECT_CALL(lib_, SendToUMA(kMetricName, kDelta1MSec, kMinSample, kMaxSample,
kNumBuckets)).WillOnce(Return(true));
ASSERT_TRUE(timer_reporter_.Start());
diff --git a/metricsd/uploader/upload_service.cc b/metricsd/uploader/upload_service.cc
index 0dc59a4..333a7e6 100644
--- a/metricsd/uploader/upload_service.cc
+++ b/metricsd/uploader/upload_service.cc
@@ -183,6 +183,7 @@
base::StatisticsRecorder::GetHistograms(&histograms);
histogram_snapshot_manager_.PrepareDeltas(
+ histograms.begin(), histograms.end(),
base::Histogram::kNoFlags, base::Histogram::kUmaTargetedHistogramFlag);
// Gather and reset the crash counters, shared with the binder threads.
diff --git a/metricsd/uploader/upload_service_test.cc b/metricsd/uploader/upload_service_test.cc
index 70112f4..0f77fe4 100644
--- a/metricsd/uploader/upload_service_test.cc
+++ b/metricsd/uploader/upload_service_test.cc
@@ -304,6 +304,8 @@
upload_service_->PersistToDisk();
EXPECT_EQ(
1, upload_service_->current_log_->uma_proto()->histogram_event().size());
+ // Destroy the old service before creating a new one.
+ upload_service_.reset();
upload_service_.reset(new UploadService(
"", base::TimeDelta(), base::TimeDelta(), private_dir_, shared_dir_));
upload_service_->InitForTest(nullptr);
@@ -325,6 +327,8 @@
// Write a bogus saved log.
EXPECT_EQ(5, base::WriteFile(upload_service_->saved_log_path_, "hello", 5));
+ // Destroy the old service before creating a new one.
+ upload_service_.reset();
upload_service_.reset(new UploadService(
"", base::TimeDelta(), base::TimeDelta(), private_dir_, shared_dir_));
diff --git a/rootdir/init-debug.rc b/rootdir/init-debug.rc
index 435d4cb..44d34d8 100644
--- a/rootdir/init-debug.rc
+++ b/rootdir/init-debug.rc
@@ -6,3 +6,6 @@
on property:persist.mmc.cache_size=*
write /sys/block/mmcblk0/cache_size ${persist.mmc.cache_size}
+
+on early-init
+ mount debugfs debugfs /sys/kernel/debug
diff --git a/rootdir/init.rc b/rootdir/init.rc
index f505faf..7723a43 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -417,9 +417,6 @@
rm /data/bugreports
symlink /data/user_de/0/com.android.shell/files/bugreports /data/bugreports
- # Separate location for storing security policy files on data
- mkdir /data/security 0711 system system
-
# Create all remaining /data root dirs so that they are made through init
# and get proper encryption policy installed
mkdir /data/backup 0700 system system
@@ -444,9 +441,6 @@
init_user0
- # Reload policy from /data/security if present.
- setprop selinux.reload_policy 1
-
# Set SELinux security contexts on upgrade or policy update.
restorecon_recursive /data
diff --git a/sdcard/Android.mk b/sdcard/Android.mk
index c5f3d1d..2d04a7f 100644
--- a/sdcard/Android.mk
+++ b/sdcard/Android.mk
@@ -5,6 +5,6 @@
LOCAL_SRC_FILES := sdcard.c
LOCAL_MODULE := sdcard
LOCAL_CFLAGS := -Wall -Wno-unused-parameter -Werror
-LOCAL_SHARED_LIBRARIES := libcutils libpackagelistparser
+LOCAL_SHARED_LIBRARIES := liblog libcutils libpackagelistparser
include $(BUILD_EXECUTABLE)
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index 9ade759..85f9415 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -32,13 +32,11 @@
OUR_TOOLS := \
getevent \
- iftop \
ioctl \
log \
nandread \
newfs_msdos \
ps \
- prlimit \
sendevent \
start \
stop \
@@ -55,6 +53,7 @@
LOCAL_CONLYFLAGS += -std=gnu99
LOCAL_SHARED_LIBRARIES := \
+ liblog \
libcutils \
libselinux \
@@ -72,7 +71,7 @@
$(LOCAL_PATH)/toolbox.c: $(intermediates)/tools.h
TOOLS_H := $(intermediates)/tools.h
-$(TOOLS_H): PRIVATE_TOOLS := $(ALL_TOOLS)
+$(TOOLS_H): PRIVATE_TOOLS := toolbox $(ALL_TOOLS)
$(TOOLS_H): PRIVATE_CUSTOM_TOOL = echo "/* file generated automatically */" > $@ ; for t in $(PRIVATE_TOOLS) ; do echo "TOOL($$t)" >> $@ ; done
$(TOOLS_H): $(LOCAL_PATH)/Android.mk
$(TOOLS_H):
diff --git a/toolbox/iftop.c b/toolbox/iftop.c
deleted file mode 100644
index 800c0f0..0000000
--- a/toolbox/iftop.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (c) 2008, The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <net/if.h>
-
-#define PROC_NET_DEV "/proc/net/dev"
-
-#define MAX_IF 8 /* max interfaces we can handle */
-
-#ifndef PAGE_SIZE
-# define PAGE_SIZE 4096
-#endif
-
-#define _STR(s) #s
-#define STR(s) _STR(s)
-
-struct if_stats {
- char name[IFNAMSIZ];
-
- unsigned int mtu;
-
- unsigned int rx_bytes;
- unsigned int rx_packets;
- unsigned int rx_errors;
- unsigned int rx_dropped;
-
- unsigned int tx_bytes;
- unsigned int tx_packets;
- unsigned int tx_errors;
- unsigned int tx_dropped;
-};
-
-static int get_mtu(const char *if_name)
-{
- struct ifreq ifr;
- int s, ret;
-
- s = socket(AF_INET, SOCK_DGRAM, 0);
- if (s < 0) {
- perror("socket");
- exit(EXIT_FAILURE);
- }
-
- memset(&ifr, 0, sizeof(struct ifreq));
- ifr.ifr_addr.sa_family = AF_INET;
- strcpy(ifr.ifr_name, if_name);
-
- ret = ioctl(s, SIOCGIFMTU, &ifr);
- if (ret < 0) {
- perror("ioctl");
- exit(EXIT_FAILURE);
- }
-
- ret = close(s);
- if (ret < 0) {
- perror("close");
- exit(EXIT_FAILURE);
- }
-
- return ifr.ifr_mtu;
-}
-
-static int get_interfaces(struct if_stats *ifs)
-{
- char buf[PAGE_SIZE];
- char *p;
- int ret, nr, fd;
-
- fd = open(PROC_NET_DEV, O_RDONLY);
- if (fd < 0) {
- perror("open");
- exit(EXIT_FAILURE);
- }
-
- ret = read(fd, buf, sizeof(buf) - 1);
- if (ret < 0) {
- perror("read");
- exit(EXIT_FAILURE);
- } else if (!ret) {
- fprintf(stderr, "reading " PROC_NET_DEV " returned premature EOF\n");
- exit(EXIT_FAILURE);
- }
- buf[ret] = '\0';
-
- /* skip down to the third line */
- p = strchr(buf, '\n');
- if (!p) {
- fprintf(stderr, "parsing " PROC_NET_DEV " failed unexpectedly\n");
- exit(EXIT_FAILURE);
- }
- p = strchr(p + 1, '\n');
- if (!p) {
- fprintf(stderr, "parsing " PROC_NET_DEV " failed unexpectedly\n");
- exit(EXIT_FAILURE);
- }
- p += 1;
-
- /*
- * Key:
- * if: (Rx) bytes packets errs drop fifo frame compressed multicast \
- * (Tx) bytes packets errs drop fifo colls carrier compressed
- */
- for (nr = 0; nr < MAX_IF; nr++) {
- char *c;
-
- ret = sscanf(p, "%" STR(IFNAMSIZ) "s", ifs->name);
- if (ret != 1) {
- fprintf(stderr, "parsing " PROC_NET_DEV " failed unexpectedly\n");
- exit(EXIT_FAILURE);
- }
-
- /*
- * This works around a bug in the proc file where large interface names
- * or Rx byte counts eat the delimiter, breaking sscanf.
- */
- c = strchr(ifs->name, ':');
- if (c)
- *c = '\0';
-
- p = strchr(p, ':') + 1;
-
- ret = sscanf(p, "%u %u %u %u %*u %*u %*u %*u %u %u %u %u %*u %*u "
- "%*u %*u\n", &ifs->rx_bytes, &ifs->rx_packets,
- &ifs->rx_errors, &ifs->rx_dropped, &ifs->tx_bytes,
- &ifs->tx_packets, &ifs->tx_errors, &ifs->tx_dropped);
- if (ret != 8) {
- fprintf(stderr, "parsing " PROC_NET_DEV " failed unexpectedly\n");
- exit(EXIT_FAILURE);
- }
-
- ifs->mtu = get_mtu(ifs->name);
-
- p = strchr(p, '\n') + 1;
- if (*p == '\0') {
- nr++;
- break;
- }
-
- ifs++;
- }
-
- ret = close(fd);
- if (ret) {
- perror("close");
- exit(EXIT_FAILURE);
- }
-
- return nr;
-}
-
-static void print_header(void)
-{
- printf(" Rx Tx\n");
- printf("%-8s %-5s %-10s %-8s %-5s %-5s %-10s %-8s %-5s %-5s\n",
- "name", "MTU", "bytes", "packets", "errs", "drpd", "bytes",
- "packets", "errs", "drpd");
-}
-
-static int print_interfaces(struct if_stats *old, struct if_stats *new, int nr)
-{
- int i = 0;
-
- while (nr--) {
- if (old->rx_packets || old->tx_packets) {
- printf("%-8s %-5u %-10u %-8u %-5u %-5u %-10u %-8u %-5u %-5u\n",
- new->name, new->mtu,
- new->rx_bytes - old->rx_bytes,
- new->rx_packets - old->rx_packets,
- new->rx_errors - old->rx_errors,
- new->rx_dropped - old->rx_dropped,
- new->tx_bytes - old->tx_bytes,
- new->tx_packets - old->tx_packets,
- new->tx_errors - old->tx_errors,
- new->tx_dropped - old->tx_dropped);
- i++;
- }
- old++;
- new++;
- }
-
- return i;
-}
-
-static void usage(const char *cmd)
-{
- fprintf(stderr, "usage: %s [ -r repeats] [ -d delay ]\n", cmd);
-}
-
-int iftop_main(int argc, char *argv[])
-{
- struct if_stats ifs[2][MAX_IF];
- int count = 0, header_interval = 22, delay = 1, i;
- unsigned int toggle = 0;
-
- for (i = 1; i < argc; i++) {
- if (!strcmp(argv[i], "-d")) {
- if (i >= argc - 1) {
- fprintf(stderr, "Option -d requires an argument.\n");
- exit(EXIT_FAILURE);
- }
- delay = atoi(argv[i++]);
- if (!delay)
- delay = 1;
- continue;
- }
- if (!strcmp(argv[i], "-r")) {
- if (i >= argc - 1) {
- fprintf(stderr, "Option -r requires an argument.\n");
- exit(EXIT_FAILURE);
- }
- header_interval = atoi(argv[i++]);
- if (header_interval < MAX_IF)
- header_interval = MAX_IF;
- continue;
- }
- if (!strcmp(argv[i], "-h")) {
- usage(argv[0]);
- exit(EXIT_SUCCESS);
- }
- usage(argv[0]);
- exit(EXIT_FAILURE);
- }
-
- get_interfaces(ifs[!toggle]);
- if (header_interval)
- print_header();
- while (1) {
- int nr;
-
- sleep(delay);
- nr = get_interfaces(ifs[toggle]);
- if (header_interval && count + nr > header_interval) {
- print_header();
- count = 0;
- }
- count += print_interfaces(ifs[!toggle], ifs[toggle], nr);
- toggle = !toggle;
- }
-
- return 0;
-}
diff --git a/toolbox/newfs_msdos.c b/toolbox/newfs_msdos.c
index 5b98a01..27ea9e8 100644
--- a/toolbox/newfs_msdos.c
+++ b/toolbox/newfs_msdos.c
@@ -695,7 +695,7 @@
(u_int)tm->tm_min));
mk4(bsx->volid, x);
mklabel(bsx->label, opt_L ? opt_L : "NO NAME");
- sprintf(buf, "FAT%u", fat);
+ snprintf(buf, sizeof(buf), "FAT%u", fat);
setstr(bsx->type, buf, sizeof(bsx->type));
if (!opt_B) {
x1 += sizeof(struct bsx);
diff --git a/toolbox/prlimit.c b/toolbox/prlimit.c
deleted file mode 100644
index 8cf202a..0000000
--- a/toolbox/prlimit.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2014, The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-
-static void
-usage(const char *s)
-{
- fprintf(stderr, "usage: %s pid resource cur max\n", s);
- exit(EXIT_FAILURE);
-}
-
-int prlimit_main(int argc, char *argv[])
-{
- pid_t pid;
- struct rlimit64 rl;
- int resource;
- int rc;
-
- if (argc != 5)
- usage(*argv);
-
- if (sscanf(argv[1], "%d", &pid) != 1)
- usage(*argv);
-
- if (sscanf(argv[2], "%d", &resource) != 1)
- usage(*argv);
-
- if (sscanf(argv[3], "%llu", &rl.rlim_cur) != 1)
- usage(*argv);
-
- if (sscanf(argv[4], "%llu", &rl.rlim_max) != 1)
- usage(*argv);
-
- printf("setting resource %d of pid %d to [%llu,%llu]\n", resource, pid,
- rl.rlim_cur, rl.rlim_max);
- rc = prlimit64(pid, resource, &rl, NULL);
- if (rc < 0) {
- perror("prlimit");
- exit(EXIT_FAILURE);
- }
-
- return 0;
-}
diff --git a/toolbox/ps.c b/toolbox/ps.c
index 7e70c71..d366f3e 100644
--- a/toolbox/ps.c
+++ b/toolbox/ps.c
@@ -57,16 +57,16 @@
int prio, nice, rtprio, sched, psr;
struct passwd *pw;
- sprintf(statline, "/proc/%d", tid ? tid : pid);
+ snprintf(statline, sizeof(statline), "/proc/%d", tid ? tid : pid);
stat(statline, &stats);
if(tid) {
- sprintf(statline, "/proc/%d/task/%d/stat", pid, tid);
+ snprintf(statline, sizeof(statline), "/proc/%d/task/%d/stat", pid, tid);
cmdline[0] = 0;
snprintf(macline, sizeof(macline), "/proc/%d/task/%d/attr/current", pid, tid);
} else {
- sprintf(statline, "/proc/%d/stat", pid);
- sprintf(cmdline, "/proc/%d/cmdline", pid);
+ snprintf(statline, sizeof(statline), "/proc/%d/stat", pid);
+ snprintf(cmdline, sizeof(cmdline), "/proc/%d/cmdline", pid);
snprintf(macline, sizeof(macline), "/proc/%d/attr/current", pid);
int fd = open(cmdline, O_RDONLY);
if(fd == 0) {
@@ -149,7 +149,7 @@
pw = getpwuid(stats.st_uid);
if(pw == 0 || (display_flags & SHOW_NUMERIC_UID)) {
- sprintf(user,"%d",(int)stats.st_uid);
+ snprintf(user,sizeof(user),"%d",(int)stats.st_uid);
} else {
strcpy(user,pw->pw_name);
}
@@ -208,7 +208,7 @@
int fd, r;
char exeline[1024];
- sprintf(exeline, "/proc/%d/exe", pid);
+ snprintf(exeline, sizeof(exeline), "/proc/%d/exe", pid);
fd = open(exeline, O_RDONLY);
if(fd == 0) {
printf(" ");
@@ -243,7 +243,7 @@
DIR *d;
struct dirent *de;
- sprintf(tmp,"/proc/%d/task",pid);
+ snprintf(tmp,sizeof(tmp),"/proc/%d/task",pid);
d = opendir(tmp);
if(d == 0) return;
diff --git a/toolbox/toolbox.c b/toolbox/toolbox.c
index 915da44..b5a942c 100644
--- a/toolbox/toolbox.c
+++ b/toolbox/toolbox.c
@@ -4,29 +4,14 @@
#include <string.h>
#include <unistd.h>
-int main(int, char **);
-
-static int toolbox_main(int argc, char **argv)
-{
- // "toolbox foo ..." is equivalent to "foo ..."
- if (argc > 1) {
- return main(argc - 1, argv + 1);
- } else {
- printf("Toolbox!\n");
- return 0;
- }
-}
-
#define TOOL(name) int name##_main(int, char**);
#include "tools.h"
#undef TOOL
-static struct
-{
- const char *name;
+static struct {
+ const char* name;
int (*func)(int, char**);
} tools[] = {
- { "toolbox", toolbox_main },
#define TOOL(name) { #name, name##_main },
#include "tools.h"
#undef TOOL
@@ -40,33 +25,35 @@
_exit(0);
}
-int main(int argc, char **argv)
-{
- int i;
- char *name = argv[0];
-
+int main(int argc, char** argv) {
// Let's assume that none of this code handles broken pipes. At least ls,
// ps, and top were broken (though I'd previously added this fix locally
// to top). We exit rather than use SIG_IGN because tools like top will
// just keep on writing to nowhere forever if we don't stop them.
signal(SIGPIPE, SIGPIPE_handler);
- if((argc > 1) && (argv[1][0] == '@')) {
- name = argv[1] + 1;
- argc--;
- argv++;
- } else {
- char *cmd = strrchr(argv[0], '/');
- if (cmd)
- name = cmd + 1;
- }
+ char* cmd = strrchr(argv[0], '/');
+ char* name = cmd ? (cmd + 1) : argv[0];
- for(i = 0; tools[i].name; i++){
- if(!strcmp(tools[i].name, name)){
+ for (size_t i = 0; tools[i].name; i++) {
+ if (!strcmp(tools[i].name, name)) {
return tools[i].func(argc, argv);
}
}
printf("%s: no such tool\n", argv[0]);
- return -1;
+ return 127;
+}
+
+int toolbox_main(int argc, char** argv) {
+ // "toolbox foo ..." is equivalent to "foo ..."
+ if (argc > 1) {
+ return main(argc - 1, argv + 1);
+ }
+
+ // Plain "toolbox" lists the tools.
+ for (size_t i = 1; tools[i].name; i++) {
+ printf("%s%c", tools[i].name, tools[i+1].name ? ' ' : '\n');
+ }
+ return 0;
}
diff --git a/toolbox/top.c b/toolbox/top.c
index 6fda132..003f4c9 100644
--- a/toolbox/top.c
+++ b/toolbox/top.c
@@ -258,29 +258,29 @@
proc->pid = proc->tid = pid;
- sprintf(filename, "/proc/%d/stat", pid);
+ snprintf(filename, sizeof(filename), "/proc/%d/stat", pid);
read_stat(filename, proc);
- sprintf(filename, "/proc/%d/cmdline", pid);
+ snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
read_cmdline(filename, proc);
- sprintf(filename, "/proc/%d/status", pid);
+ snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
read_status(filename, proc);
read_policy(pid, proc);
proc->num_threads = 0;
} else {
- sprintf(filename, "/proc/%d/cmdline", pid);
+ snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
read_cmdline(filename, &cur_proc);
- sprintf(filename, "/proc/%d/status", pid);
+ snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
read_status(filename, &cur_proc);
proc = NULL;
}
- sprintf(filename, "/proc/%d/task", pid);
+ snprintf(filename, sizeof(filename), "/proc/%d/task", pid);
task_dir = opendir(filename);
if (!task_dir) continue;
@@ -295,7 +295,7 @@
proc->pid = pid; proc->tid = tid;
- sprintf(filename, "/proc/%d/task/%d/stat", pid, tid);
+ snprintf(filename, sizeof(filename), "/proc/%d/task/%d/stat", pid, tid);
read_stat(filename, proc);
read_policy(tid, proc);
@@ -484,7 +484,7 @@
if (user && user->pw_name) {
user_str = user->pw_name;
} else {
- snprintf(user_buf, 20, "%d", proc->uid);
+ snprintf(user_buf, sizeof(user_buf), "%d", proc->uid);
user_str = user_buf;
}
if (!threads) {
diff --git a/trusty/libtrusty/tipc-test/tipc_test.c b/trusty/libtrusty/tipc-test/tipc_test.c
index 55d5ee6..1fb34c9 100644
--- a/trusty/libtrusty/tipc-test/tipc_test.c
+++ b/trusty/libtrusty/tipc-test/tipc_test.c
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
+#include <sys/uio.h>
#include <trusty/tipc.h>
@@ -80,6 +81,8 @@
" ta2ta-ipc - execute TA to TA unittest\n"
" dev-uuid - print device uuid\n"
" ta-access - test ta-access flags\n"
+" writev - writev test\n"
+" readv - readv test\n"
"\n"
;
@@ -93,7 +96,7 @@
{
fprintf (stderr, usage, prog);
if (verbose)
- fprintf (stderr, usage_long);
+ fprintf (stderr, "%s", usage_long);
exit(code);
}
@@ -692,6 +695,171 @@
}
+static int writev_test(uint repeat, uint msgsz, bool var)
+{
+ uint i;
+ ssize_t rc;
+ size_t msg_len;
+ int echo_fd = -1;
+ char tx0_buf[msgsz];
+ char tx1_buf[msgsz];
+ char rx_buf [msgsz];
+ struct iovec iovs[2]= {{tx0_buf, 0}, {tx1_buf, 0}};
+
+ if (!opt_silent) {
+ printf("%s: repeat %u: msgsz %u: variable %s\n",
+ __func__, repeat, msgsz, var ? "true" : "false");
+ }
+
+ echo_fd = tipc_connect(dev_name, echo_name);
+ if (echo_fd < 0) {
+ fprintf(stderr, "Failed to connect to service\n");
+ return echo_fd;
+ }
+
+ for (i = 0; i < repeat; i++) {
+
+ msg_len = msgsz;
+ if (opt_variable && msgsz) {
+ msg_len = rand() % msgsz;
+ }
+
+ iovs[0].iov_len = msg_len / 3;
+ iovs[1].iov_len = msg_len - iovs[0].iov_len;
+
+ memset(tx0_buf, i + 1, iovs[0].iov_len);
+ memset(tx1_buf, i + 2, iovs[1].iov_len);
+ memset(rx_buf, i + 3, sizeof(rx_buf));
+
+ rc = writev(echo_fd, iovs, 2);
+ if (rc < 0) {
+ perror("writev_test: writev");
+ break;
+ }
+
+ if ((size_t)rc != msg_len) {
+ fprintf(stderr,
+ "%s: %s: data size mismatch (%zd vs. %zd)\n",
+ __func__, "writev", (size_t)rc, msg_len);
+ break;
+ }
+
+ rc = read(echo_fd, rx_buf, sizeof(rx_buf));
+ if (rc < 0) {
+ perror("writev_test: read");
+ break;
+ }
+
+ if ((size_t)rc != msg_len) {
+ fprintf(stderr,
+ "%s: %s: data size mismatch (%zd vs. %zd)\n",
+ __func__, "read", (size_t)rc, msg_len);
+ break;
+ }
+
+ if (memcmp(tx0_buf, rx_buf, iovs[0].iov_len)) {
+ fprintf(stderr, "%s: data mismatch: buf 0\n", __func__);
+ break;
+ }
+
+ if (memcmp(tx1_buf, rx_buf + iovs[0].iov_len, iovs[1].iov_len)) {
+ fprintf(stderr, "%s: data mismatch, buf 1\n", __func__);
+ break;
+ }
+ }
+
+ tipc_close(echo_fd);
+
+ if (!opt_silent) {
+ printf("%s: done\n",__func__);
+ }
+
+ return 0;
+}
+
+static int readv_test(uint repeat, uint msgsz, bool var)
+{
+ uint i;
+ ssize_t rc;
+ size_t msg_len;
+ int echo_fd = -1;
+ char tx_buf [msgsz];
+ char rx0_buf[msgsz];
+ char rx1_buf[msgsz];
+ struct iovec iovs[2]= {{rx0_buf, 0}, {rx1_buf, 0}};
+
+ if (!opt_silent) {
+ printf("%s: repeat %u: msgsz %u: variable %s\n",
+ __func__, repeat, msgsz, var ? "true" : "false");
+ }
+
+ echo_fd = tipc_connect(dev_name, echo_name);
+ if (echo_fd < 0) {
+ fprintf(stderr, "Failed to connect to service\n");
+ return echo_fd;
+ }
+
+ for (i = 0; i < repeat; i++) {
+
+ msg_len = msgsz;
+ if (opt_variable && msgsz) {
+ msg_len = rand() % msgsz;
+ }
+
+ iovs[0].iov_len = msg_len / 3;
+ iovs[1].iov_len = msg_len - iovs[0].iov_len;
+
+ memset(tx_buf, i + 1, sizeof(tx_buf));
+ memset(rx0_buf, i + 2, iovs[0].iov_len);
+ memset(rx1_buf, i + 3, iovs[1].iov_len);
+
+ rc = write(echo_fd, tx_buf, msg_len);
+ if (rc < 0) {
+ perror("readv_test: write");
+ break;
+ }
+
+ if ((size_t)rc != msg_len) {
+ fprintf(stderr,
+ "%s: %s: data size mismatch (%zd vs. %zd)\n",
+ __func__, "write", (size_t)rc, msg_len);
+ break;
+ }
+
+ rc = readv(echo_fd, iovs, 2);
+ if (rc < 0) {
+ perror("readv_test: readv");
+ break;
+ }
+
+ if ((size_t)rc != msg_len) {
+ fprintf(stderr,
+ "%s: %s: data size mismatch (%zd vs. %zd)\n",
+ __func__, "write", (size_t)rc, msg_len);
+ break;
+ }
+
+ if (memcmp(rx0_buf, tx_buf, iovs[0].iov_len)) {
+ fprintf(stderr, "%s: data mismatch: buf 0\n", __func__);
+ break;
+ }
+
+ if (memcmp(rx1_buf, tx_buf + iovs[0].iov_len, iovs[1].iov_len)) {
+ fprintf(stderr, "%s: data mismatch, buf 1\n", __func__);
+ break;
+ }
+ }
+
+ tipc_close(echo_fd);
+
+ if (!opt_silent) {
+ printf("%s: done\n",__func__);
+ }
+
+ return 0;
+}
+
+
int main(int argc, char **argv)
{
int rc = 0;
@@ -735,6 +903,10 @@
rc = dev_uuid_test();
} else if (strcmp(test_name, "ta-access") == 0) {
rc = ta_access_test();
+ } else if (strcmp(test_name, "writev") == 0) {
+ rc = writev_test(opt_repeat, opt_msgsize, opt_variable);
+ } else if (strcmp(test_name, "readv") == 0) {
+ rc = readv_test(opt_repeat, opt_msgsize, opt_variable);
} else {
fprintf(stderr, "Unrecognized test name '%s'\n", test_name);
print_usage_and_exit(argv[0], EXIT_FAILURE, true);
diff --git a/trusty/nvram/Android.mk b/trusty/nvram/Android.mk
new file mode 100644
index 0000000..18c54d5
--- /dev/null
+++ b/trusty/nvram/Android.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2016 The Android Open-Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# nvram.trusty is the Trusty NVRAM HAL module.
+include $(CLEAR_VARS)
+LOCAL_MODULE := nvram.trusty
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+ module.c \
+ trusty_nvram_implementation.cpp
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := -Wall -Werror -Wextra -fvisibility=hidden
+LOCAL_STATIC_LIBRARIES := libnvram-hal
+LOCAL_SHARED_LIBRARIES := libtrusty libnvram-messages liblog
+include $(BUILD_SHARED_LIBRARY)
diff --git a/trusty/nvram/module.c b/trusty/nvram/module.c
new file mode 100644
index 0000000..06819c0
--- /dev/null
+++ b/trusty/nvram/module.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hardware/nvram.h>
+
+// This function is defined in trusty_nvram_implementation.cpp.
+int trusty_nvram_open(const hw_module_t* module,
+ const char* device_id,
+ hw_device_t** device_ptr);
+
+static struct hw_module_methods_t nvram_module_methods = {
+ .open = trusty_nvram_open,
+};
+
+struct nvram_module HAL_MODULE_INFO_SYM
+ __attribute__((visibility("default"))) = {
+ .common = {.tag = HARDWARE_MODULE_TAG,
+ .module_api_version = NVRAM_MODULE_API_VERSION_0_1,
+ .hal_api_version = HARDWARE_HAL_API_VERSION,
+ .id = NVRAM_HARDWARE_MODULE_ID,
+ .name = "Trusty NVRAM HAL",
+ .author = "The Android Open Source Project",
+ .methods = &nvram_module_methods,
+ .dso = 0,
+ .reserved = {}},
+};
diff --git a/trusty/nvram/trusty_nvram_implementation.cpp b/trusty/nvram/trusty_nvram_implementation.cpp
new file mode 100644
index 0000000..39496b4
--- /dev/null
+++ b/trusty/nvram/trusty_nvram_implementation.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include <hardware/nvram.h>
+#include <trusty/tipc.h>
+
+#define LOG_TAG "TrustyNVRAM"
+#include <log/log.h>
+
+#include <nvram/hal/nvram_device_adapter.h>
+#include <nvram/messages/blob.h>
+#include <nvram/messages/nvram_messages.h>
+
+namespace {
+
+// Character device to open for Trusty IPC connections.
+const char kTrustyDeviceName[] = "/dev/trusty-ipc-dev0";
+
+// App identifier of the NVRAM app.
+const char kTrustyNvramAppId[] = "com.android.trusty.nvram";
+
+// |TrustyNvramImplementation| proxies requests to the Trusty NVRAM app. It
+// serializes the request objects, sends it to the Trusty app and finally reads
+// back the result and decodes it.
+class TrustyNvramImplementation : public nvram::NvramImplementation {
+ public:
+ ~TrustyNvramImplementation() override;
+
+ void Execute(const nvram::Request& request,
+ nvram::Response* response) override;
+
+ private:
+ // Connects the IPC channel to the Trusty app if it is not already open.
+ // Returns true if the channel is open, false on errors.
+ bool Connect();
+
+ // Dispatches a command to the trust app. Returns true if successful (note
+ // that the response may still indicate an error on the Trusty side), false if
+ // there are any I/O or encoding/decoding errors.
+ bool SendRequest(const nvram::Request& request,
+ nvram::Response* response);
+
+ // The file descriptor for the IPC connection to the Trusty app.
+ int tipc_nvram_fd_ = -1;
+
+ // Response buffer. This puts a hard size limit on the responses from the
+ // Trusty app. 4096 matches the maximum IPC message size currently supported
+ // by Trusty.
+ uint8_t response_buffer_[4096];
+};
+
+TrustyNvramImplementation::~TrustyNvramImplementation() {
+ if (tipc_nvram_fd_ != -1) {
+ tipc_close(tipc_nvram_fd_);
+ tipc_nvram_fd_ = -1;
+ }
+}
+
+void TrustyNvramImplementation::Execute(const nvram::Request& request,
+ nvram::Response* response) {
+ if (!SendRequest(request, response)) {
+ response->result = NV_RESULT_INTERNAL_ERROR;
+ }
+}
+
+bool TrustyNvramImplementation::Connect() {
+ if (tipc_nvram_fd_ != -1) {
+ return true;
+ }
+
+ int rc = tipc_connect(kTrustyDeviceName, kTrustyNvramAppId);
+ if (rc < 0) {
+ ALOGE("Failed to connect to Trusty NVRAM app: %s\n", strerror(-rc));
+ return false;
+ }
+
+ tipc_nvram_fd_ = rc;
+ return true;
+}
+
+bool TrustyNvramImplementation::SendRequest(const nvram::Request& request,
+ nvram::Response* response) {
+ if (!Connect()) {
+ return false;
+ }
+
+ nvram::Blob request_buffer;
+ if (!nvram::Encode(request, &request_buffer)) {
+ ALOGE("Failed to encode NVRAM request.\n");
+ return false;
+ }
+
+ ssize_t rc =
+ write(tipc_nvram_fd_, request_buffer.data(), request_buffer.size());
+ if (rc < 0) {
+ ALOGE("Failed to send NVRAM request: %s\n", strerror(-rc));
+ return false;
+ }
+ if (static_cast<size_t>(rc) != request_buffer.size()) {
+ ALOGE("Failed to send full request buffer: %zd\n", rc);
+ return false;
+ }
+
+ rc = read(tipc_nvram_fd_, response_buffer_, sizeof(response_buffer_));
+ if (rc < 0) {
+ ALOGE("Failed to read NVRAM response: %s\n", strerror(-rc));
+ return false;
+ }
+
+ if (static_cast<size_t>(rc) >= sizeof(response_buffer_)) {
+ ALOGE("NVRAM response exceeds response buffer size.\n");
+ return false;
+ }
+
+ if (!nvram::Decode(response_buffer_, static_cast<size_t>(rc), response)) {
+ ALOGE("Failed to decode NVRAM response.\n");
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace
+
+extern "C" int trusty_nvram_open(const hw_module_t* module,
+ const char* device_id,
+ hw_device_t** device_ptr) {
+ if (strcmp(NVRAM_HARDWARE_DEVICE_ID, device_id) != 0) {
+ return -EINVAL;
+ }
+
+ nvram::NvramDeviceAdapter* adapter =
+ new nvram::NvramDeviceAdapter(module, new TrustyNvramImplementation);
+ *device_ptr = adapter->as_device();
+ return 0;
+}