diff options
-rw-r--r-- | board/host/dcrypto.h | 44 | ||||
-rw-r--r-- | chip/g/dcrypto/dcrypto.h | 3 | ||||
-rw-r--r-- | chip/g/dcrypto/internal.h | 2 | ||||
-rw-r--r-- | chip/host/build.mk | 26 | ||||
-rw-r--r-- | chip/host/dcrypto/README.md | 13 | ||||
-rw-r--r-- | chip/host/dcrypto/aes.c | 35 | ||||
-rw-r--r-- | chip/host/dcrypto/app_cipher.c | 33 | ||||
-rw-r--r-- | chip/host/dcrypto/app_key.c | 31 | ||||
-rw-r--r-- | chip/host/dcrypto/sha256.c | 18 | ||||
-rw-r--r-- | include/config.h | 9 | ||||
-rw-r--r-- | test/test_config.h | 1 |
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 */ |