summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 */