summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllen Webb <allenwebb@google.com>2018-08-17 17:45:26 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-09-07 18:36:33 -0700
commit5c5555a49d89154f14efa0c68c99938ef1313b73 (patch)
treeff53547f53396b590e39630c30c862908fdcacd0
parent6a9a3a62732ff31e247a9eb61a5f4e7c53154ee5 (diff)
downloadchrome-ec-5c5555a49d89154f14efa0c68c99938ef1313b73.tar.gz
host: Add dcrypto definitions that can be used by fuzzing targets.
These definitions provide the necessary dcrypto functionality for fuzzing pinweaver. They can be built out as needed to support further fuzzing. BRANCH=none BUG=chromium:876582 TEST=make -j buildfuzztests && ./build/host/cr50_fuzz/cr50_fuzz.exe (with the cr50_fuzz CL) Change-Id: I36ce874efab5dbc59825d126f6079b7b6d0da9ef Signed-off-by: Allen Webb <allenwebb@google.com> Reviewed-on: https://chromium-review.googlesource.com/1180573 Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--board/host/dcrypto.h44
-rw-r--r--chip/g/dcrypto/dcrypto.h3
-rw-r--r--chip/g/dcrypto/internal.h2
-rw-r--r--chip/host/build.mk26
-rw-r--r--chip/host/dcrypto/README.md13
-rw-r--r--chip/host/dcrypto/aes.c35
-rw-r--r--chip/host/dcrypto/app_cipher.c33
-rw-r--r--chip/host/dcrypto/app_key.c31
-rw-r--r--chip/host/dcrypto/sha256.c18
-rw-r--r--include/config.h9
-rw-r--r--test/test_config.h1
11 files changed, 199 insertions, 16 deletions
diff --git a/board/host/dcrypto.h b/board/host/dcrypto.h
index 48bde62592..31f04e51aa 100644
--- a/board/host/dcrypto.h
+++ b/board/host/dcrypto.h
@@ -11,26 +11,23 @@
#ifndef __CROS_EC_DCRYPTO_HOST_H
#define __CROS_EC_DCRYPTO_HOST_H
-
-#include <sha256.h>
#include <stdint.h>
#include <string.h>
-#define AES256_BLOCK_CIPHER_KEY_SIZE 32
-#define SHA256_DIGEST_SIZE 32
+/* Allow tests to return a faked result for the purpose of testing. If
+ * this is not set, a combination of cryptoc and openssl are used for the
+ * dcrypto implementation.
+ */
+#ifndef CONFIG_DCRYPTO_MOCK
-#define HASH_CTX sha256_ctx
+/* If not using the mock struct definitions, use the ones from Cr50. */
+#include "chip/g/dcrypto/dcrypto.h"
-enum dcrypto_appid {
- RESERVED = 0,
- NVMEM = 1,
- U2F_ATTEST = 2,
- U2F_ORIGIN = 3,
- U2F_WRAP = 4,
- PERSO_AUTH = 5,
- PINWEAVER = 6,
- /* This enum value should not exceed 7. */
-};
+#else /* defined(CONFIG_DCRYPTO_MOCK) */
+
+#include <sha256.h>
+
+#define HASH_CTX sha256_ctx
/* Used as a replacement for declarations in cryptoc that are used by Cr50, but
* add unnecessary complexity to the test code.
@@ -42,9 +39,22 @@ struct dcrypto_mock_ctx_t {
#define LITE_SHA256_CTX struct HASH_CTX
void HASH_update(struct HASH_CTX *ctx, const void *data, size_t len);
-
uint8_t *HASH_final(struct HASH_CTX *ctx);
+#define AES256_BLOCK_CIPHER_KEY_SIZE 32
+#define SHA256_DIGEST_SIZE 32
+
+enum dcrypto_appid {
+ RESERVED = 0,
+ NVMEM = 1,
+ U2F_ATTEST = 2,
+ U2F_ORIGIN = 3,
+ U2F_WRAP = 4,
+ PERSO_AUTH = 5,
+ PINWEAVER = 6,
+ /* This enum value should not exceed 7. */
+};
+
void DCRYPTO_SHA256_init(LITE_SHA256_CTX *ctx, uint32_t sw_required);
void DCRYPTO_HMAC_SHA256_init(LITE_HMAC_CTX *ctx, const void *key,
@@ -63,4 +73,6 @@ void DCRYPTO_appkey_finish(struct APPKEY_CTX *ctx);
int DCRYPTO_appkey_derive(enum dcrypto_appid appid, const uint32_t input[8],
uint32_t output[8]);
+#endif /* CONFIG_DCRYPTO_MOCK */
+
#endif /* __CROS_EC_HOST_DCRYPTO_H */
diff --git a/chip/g/dcrypto/dcrypto.h b/chip/g/dcrypto/dcrypto.h
index 5210710b72..93763b1f26 100644
--- a/chip/g/dcrypto/dcrypto.h
+++ b/chip/g/dcrypto/dcrypto.h
@@ -293,6 +293,9 @@ enum dcrypto_appid {
};
struct APPKEY_CTX {
+#ifdef TEST_FUZZ
+ uint8_t unused_for_cxx_compatibility;
+#endif
};
int DCRYPTO_ladder_compute_frk2(size_t major_fw_version, uint8_t *frk2);
diff --git a/chip/g/dcrypto/internal.h b/chip/g/dcrypto/internal.h
index 4baf175760..3e546e90a2 100644
--- a/chip/g/dcrypto/internal.h
+++ b/chip/g/dcrypto/internal.h
@@ -169,12 +169,14 @@ uint32_t dcrypto_dmem_load(size_t offset, const void *words, size_t n_words);
/*
* Key ladder.
*/
+#ifndef __cplusplus
enum dcrypto_appid; /* Forward declaration. */
int dcrypto_ladder_compute_usr(enum dcrypto_appid id,
const uint32_t usr_salt[8]);
int dcrypto_ladder_derive(enum dcrypto_appid appid, const uint32_t salt[8],
const uint32_t input[8], uint32_t output[8]);
+#endif
#endif /* ! __EC_CHIP_G_DCRYPTO_INTERNAL_H */
diff --git a/chip/host/build.mk b/chip/host/build.mk
index 40d2604fcb..92284b072a 100644
--- a/chip/host/build.mk
+++ b/chip/host/build.mk
@@ -12,3 +12,29 @@ chip-y=system.o gpio.o uart.o persistence.o flash.o lpc.o reboot.o i2c.o \
clock.o
chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o
chip-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_phy.o
+
+ifeq ($(CONFIG_DCRYPTO),y)
+CPPFLAGS += -I$(abspath ./chip/g)
+dirs-y += chip/g/dcrypto
+endif
+dirs-y += chip/host/dcrypto
+
+chip-$(CONFIG_DCRYPTO)+= dcrypto/aes.o
+chip-$(CONFIG_DCRYPTO)+= dcrypto/app_cipher.o
+chip-$(CONFIG_DCRYPTO)+= dcrypto/app_key.o
+chip-$(CONFIG_DCRYPTO)+= dcrypto/sha256.o
+
+# Object files that can be shared with the Cr50 dcrypto implementation
+chip-$(CONFIG_DCRYPTO)+= ../g/dcrypto/hmac.o
+
+ifeq ($(CONFIG_DCRYPTO),y)
+CRYPTOCLIB := $(realpath ../../third_party/cryptoc)
+
+# Force the external build each time, so it can look for changed sources.
+.PHONY: $(out)/cryptoc/libcryptoc.a
+$(out)/cryptoc/libcryptoc.a:
+ $(MAKE) obj=$(realpath $(out))/cryptoc SUPPORT_UNALIGNED=1 \
+ CONFIG_UPTO_SHA512=$(CONFIG_UPTO_SHA512) -C $(CRYPTOCLIB)
+
+CPPFLAGS += -I$(CRYPTOCLIB)/include
+endif # end CONFIG_DCRYPTO
diff --git a/chip/host/dcrypto/README.md b/chip/host/dcrypto/README.md
new file mode 100644
index 0000000000..6812dde311
--- /dev/null
+++ b/chip/host/dcrypto/README.md
@@ -0,0 +1,13 @@
+# Rough Dcrypto Implementation on Host for Fuzzing Targets.
+
+This implementation of the dcrypto API is not complete, but provides the needed
+function definitions to fuzz Cr50 code.
+The the following should be noted:
+* A complete implementation of dcrypto does not add any extra coverage since the
+ dcrypto code here doesn't match the Cr50 implementation that depends on
+ a specific hardware accelerator.
+* The input data comes from a fuzzer so storage encryption isn't necessary—no
+ user data is handled.
+* For fuzzing fully implementing the crypto functionality isn't useful for the
+ purpose of finding bugs--it makes the fuzzer take longer to execute without
+ providing any benefit for the extra cycles.
diff --git a/chip/host/dcrypto/aes.c b/chip/host/dcrypto/aes.c
new file mode 100644
index 0000000000..5c944a0c95
--- /dev/null
+++ b/chip/host/dcrypto/aes.c
@@ -0,0 +1,35 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <openssl/evp.h>
+
+#include "dcrypto.h"
+#include "registers.h"
+
+int DCRYPTO_aes_ctr(uint8_t *out, const uint8_t *key, uint32_t key_bits,
+ const uint8_t *iv, const uint8_t *in, size_t in_len)
+{
+ EVP_CIPHER_CTX *ctx;
+ int ret = 0;
+ int out_len = 0;
+
+ ctx = EVP_CIPHER_CTX_new();
+ if (!ctx)
+ return 0;
+
+ if (EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, iv) != 1)
+ goto cleanup;
+
+ if (EVP_EncryptUpdate(ctx, out, &out_len, in, in_len) != 1)
+ goto cleanup;
+
+ if (EVP_EncryptFinal(ctx, out + out_len, &out_len) != 1)
+ goto cleanup;
+ ret = 1;
+
+cleanup:
+ EVP_CIPHER_CTX_free(ctx);
+ return ret;
+}
diff --git a/chip/host/dcrypto/app_cipher.c b/chip/host/dcrypto/app_cipher.c
new file mode 100644
index 0000000000..af6c2c4beb
--- /dev/null
+++ b/chip/host/dcrypto/app_cipher.c
@@ -0,0 +1,33 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "dcrypto.h"
+#include "util.h"
+
+void app_compute_hash(uint8_t *p_buf, size_t num_bytes,
+ uint8_t *p_hash, size_t hash_len)
+{
+ uint8_t digest[SHA256_DIGEST_SIZE];
+
+ /*
+ * Use the built in dcrypto engine to generate the sha1 hash of the
+ * buffer.
+ */
+ DCRYPTO_SHA256_hash((uint8_t *)p_buf, num_bytes, digest);
+
+ memcpy(p_hash, digest, MIN(hash_len, sizeof(digest)));
+
+ if (hash_len > sizeof(digest))
+ memset(p_hash + sizeof(digest), 0,
+ hash_len - sizeof(digest));
+}
+
+int app_cipher(const void *salt_p, void *out_p, const void *in_p, size_t size)
+{
+ /* See README.md for while this is a passthrough. */
+ memcpy(out_p, in_p, size);
+ return 1;
+}
+
diff --git a/chip/host/dcrypto/app_key.c b/chip/host/dcrypto/app_key.c
new file mode 100644
index 0000000000..58066c84ba
--- /dev/null
+++ b/chip/host/dcrypto/app_key.c
@@ -0,0 +1,31 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "dcrypto.h"
+
+static int dcrypto_appkey_init_flag_ = -1;
+
+int DCRYPTO_appkey_init(enum dcrypto_appid appid, struct APPKEY_CTX *ctx)
+{
+ if (dcrypto_appkey_init_flag_ != -1)
+ return 0;
+
+ dcrypto_appkey_init_flag_ = appid;
+ return 1;
+}
+
+void DCRYPTO_appkey_finish(struct APPKEY_CTX *ctx)
+{
+ memset(ctx, 0, sizeof(struct APPKEY_CTX));
+ dcrypto_appkey_init_flag_ = -1;
+}
+
+int DCRYPTO_appkey_derive(enum dcrypto_appid appid, const uint32_t input[8],
+ uint32_t output[8])
+{
+ /* See README.md for while this is a passthrough. */
+ memcpy(output, input, SHA256_DIGEST_SIZE);
+ return 1;
+}
diff --git a/chip/host/dcrypto/sha256.c b/chip/host/dcrypto/sha256.c
new file mode 100644
index 0000000000..429588c8ac
--- /dev/null
+++ b/chip/host/dcrypto/sha256.c
@@ -0,0 +1,18 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "dcrypto.h"
+
+void DCRYPTO_SHA256_init(LITE_SHA256_CTX *ctx, uint32_t sw_required)
+{
+ SHA256_init(ctx);
+}
+
+const uint8_t *DCRYPTO_SHA256_hash(const void *data, uint32_t n,
+ uint8_t *digest)
+{
+ SHA256_hash(data, n, digest);
+ return digest;
+}
diff --git a/include/config.h b/include/config.h
index 935206e426..429339654a 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1157,8 +1157,17 @@
/*
* When enabled, build in support for software & hardware crypto;
* only supported on CR50.
+ *
+ * If this is enabled on the host board, a minimal implementation is included to
+ * allow fuzzing targets to fuzz code that depends on dcrypto.
*/
#undef CONFIG_DCRYPTO
+/*
+ * This provides struct definitions and function declarations that can be
+ * implemented by unit tests for testing code that depends on dcrypto.
+ * This should not be set at the same time as CONFIG_DCRYPTO.
+ */
+#undef CONFIG_DCRYPTO_MOCK
/*
* When enabled, RSA 2048 bit keygen gets a 40% performance boost,
diff --git a/test/test_config.h b/test/test_config.h
index be1068ac33..5c57de1be1 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -266,6 +266,7 @@ enum nvmem_vars {
#endif /* TEST_NVMEM_VARS */
#ifdef TEST_PINWEAVER
+#define CONFIG_DCRYPTO_MOCK
#define CONFIG_PINWEAVER
#define CONFIG_SHA256
#endif /* TEST_PINWEAVER */