mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 09:01:35 +00:00
CR50: port dcrypto/cr50 code to depend on third_party/cryptoc
Port SHA and P256 code to depend on third_party/cryptoc. Remove config options CONFIG_SHA1, and CONFIG_SHA256 as these are provided by third_party/cryptoc. Also remove unused config options CONFIG_SHA384, CONFIG_SHA512. Crypto functions prefixed by dcrypto_ (declared in internal.h ), DCRYPTO_ (declared in dcrypto.h) are implemented under chip/g/dcrypto, and otherwise are implemented under third_party/cryptoc. BRANCH=none BUG=chrome-os-partner:43025,chrome-os-partner:47524,chrome-os-partner:53782 TEST=all tests in test/tpm_test/tpmtest.py pass Change-Id: If7da02849aba9703573559370af5fae721d594fc Signed-off-by: nagendra modadugu <ngm@google.com> Reviewed-on: https://chromium-review.googlesource.com/340853 Commit-Ready: Nagendra Modadugu <ngm@google.com> Tested-by: Nagendra Modadugu <ngm@google.com> Reviewed-by: Nagendra Modadugu <ngm@google.com> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
This commit is contained in:
committed by
chrome-bot
parent
abe2a55191
commit
aca616c551
@@ -25,6 +25,8 @@
|
||||
/* Define interrupt and gpio structs */
|
||||
#include "gpio_list.h"
|
||||
|
||||
#include "cryptoc/sha.h"
|
||||
|
||||
/*
|
||||
* TODO: NV_MEMORY_SIZE is defined in 2 places. Here and in
|
||||
* /src/third_party/tmp2/Implementation.h. This needs to be
|
||||
@@ -209,7 +211,7 @@ void sys_rst_asserted(enum gpio_signal signal)
|
||||
void nvmem_compute_sha(uint8_t *p_buf, int num_bytes,
|
||||
uint8_t *p_sha, int sha_len)
|
||||
{
|
||||
uint8_t sha1_digest[SHA1_DIGEST_SIZE];
|
||||
uint8_t sha1_digest[SHA_DIGEST_SIZE];
|
||||
/*
|
||||
* Taking advantage of the built in dcrypto engine to generate
|
||||
* a CRC-like value that can be used to validate contents of an
|
||||
|
||||
@@ -80,8 +80,6 @@
|
||||
|
||||
/* Include crypto stuff, both software and hardware. */
|
||||
#define CONFIG_DCRYPTO
|
||||
#define CONFIG_SHA1
|
||||
#define CONFIG_SHA256
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
|
||||
@@ -60,9 +60,11 @@ CPPFLAGS += -I$(abspath ./test)
|
||||
|
||||
# Make sure the context of the software sha256 implementation fits. If it ever
|
||||
# increases, a compile time assert will fire in tpm2/hash.c.
|
||||
CFLAGS += -DUSER_MIN_HASH_STATE_SIZE=210
|
||||
CFLAGS += -DUSER_MIN_HASH_STATE_SIZE=112
|
||||
# Configure TPM2 headers accordingly.
|
||||
CFLAGS += -DEMBEDDED_MODE=1
|
||||
# Configure cryptoc headers to handle unaligned accesses.
|
||||
CFLAGS += -DSUPPORT_UNALIGNED=1
|
||||
|
||||
# Add dependencies on that library
|
||||
$(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: LDFLAGS_EXTRA += -L$(out)/tpm2 -ltpm2
|
||||
|
||||
@@ -10,8 +10,12 @@
|
||||
#include "TPMB.h"
|
||||
|
||||
#include "trng.h"
|
||||
#include "util.h"
|
||||
#include "dcrypto.h"
|
||||
|
||||
#include "cryptoc/p256.h"
|
||||
#include "cryptoc/p256_ecdsa.h"
|
||||
|
||||
static void reverse_tpm2b(TPM2B *b)
|
||||
{
|
||||
reverse(b->buffer, b->size);
|
||||
@@ -42,8 +46,8 @@ BOOL _cpri__EccIsPointOnCurve(TPM_ECC_CURVE curve_id, TPMS_ECC_POINT *q)
|
||||
reverse_tpm2b(&q->x.b);
|
||||
reverse_tpm2b(&q->y.b);
|
||||
|
||||
result = DCRYPTO_p256_valid_point((p256_int *) q->x.b.buffer,
|
||||
(p256_int *) q->y.b.buffer);
|
||||
result = p256_is_valid_point((p256_int *) q->x.b.buffer,
|
||||
(p256_int *) q->y.b.buffer);
|
||||
|
||||
reverse_tpm2b(&q->x.b);
|
||||
reverse_tpm2b(&q->y.b);
|
||||
@@ -198,10 +202,10 @@ CRYPT_RESULT _cpri__SignEcc(
|
||||
|
||||
reverse_tpm2b(&d->b);
|
||||
|
||||
DCRYPTO_p256_ecdsa_sign((p256_int *) d->b.buffer,
|
||||
&p256_digest,
|
||||
(p256_int *) r->b.buffer,
|
||||
(p256_int *) s->b.buffer);
|
||||
p256_ecdsa_sign((p256_int *) d->b.buffer,
|
||||
&p256_digest,
|
||||
(p256_int *) r->b.buffer,
|
||||
(p256_int *) s->b.buffer);
|
||||
reverse_tpm2b(&d->b);
|
||||
|
||||
r->b.size = sizeof(p256_int);
|
||||
@@ -242,7 +246,7 @@ CRYPT_RESULT _cpri__ValidateSignatureEcc(
|
||||
reverse_tpm2b(&r->b);
|
||||
reverse_tpm2b(&s->b);
|
||||
|
||||
result = DCRYPTO_p256_ecdsa_verify(
|
||||
result = p256_ecdsa_verify(
|
||||
(p256_int *) q->x.b.buffer,
|
||||
(p256_int *) q->y.b.buffer,
|
||||
&p256_digest,
|
||||
|
||||
@@ -42,6 +42,7 @@ uint16_t _cpri__GetHashBlockSize(TPM_ALG_ID alg)
|
||||
return lookup_hash_info(alg)->blockSize;
|
||||
}
|
||||
|
||||
BUILD_ASSERT(sizeof(LITE_SHA256_CTX) == USER_MIN_HASH_STATE_SIZE);
|
||||
BUILD_ASSERT(sizeof(CPRI_HASH_STATE) == sizeof(EXPORT_HASH_STATE));
|
||||
void _cpri__ImportExportHashState(CPRI_HASH_STATE *osslFmt,
|
||||
EXPORT_HASH_STATE *externalFmt,
|
||||
@@ -99,11 +100,11 @@ uint16_t _cpri__StartHash(TPM_ALG_ID alg, BOOL sequence,
|
||||
switch (alg) {
|
||||
case TPM_ALG_SHA1:
|
||||
DCRYPTO_SHA1_init(ctx, sequence);
|
||||
result = DCRYPTO_HASH_size(ctx);
|
||||
result = HASH_size(ctx);
|
||||
break;
|
||||
case TPM_ALG_SHA256:
|
||||
DCRYPTO_SHA256_init(ctx, sequence);
|
||||
result = DCRYPTO_HASH_size(ctx);
|
||||
result = HASH_size(ctx);
|
||||
break;
|
||||
/* TODO: add support for SHA384 and SHA512
|
||||
* case TPM_ALG_SHA384:
|
||||
@@ -128,7 +129,7 @@ void _cpri__UpdateHash(CPRI_HASH_STATE *state, uint32_t in_len,
|
||||
{
|
||||
struct HASH_CTX *ctx = (struct HASH_CTX *) state->state;
|
||||
|
||||
DCRYPTO_HASH_update(ctx, in, in_len);
|
||||
HASH_update(ctx, in, in_len);
|
||||
}
|
||||
|
||||
uint16_t _cpri__CompleteHash(CPRI_HASH_STATE *state,
|
||||
@@ -136,8 +137,8 @@ uint16_t _cpri__CompleteHash(CPRI_HASH_STATE *state,
|
||||
{
|
||||
struct HASH_CTX *ctx = (struct HASH_CTX *) state->state;
|
||||
|
||||
out_len = MIN(DCRYPTO_HASH_size(ctx), out_len);
|
||||
memcpy(out, DCRYPTO_HASH_final(ctx), out_len);
|
||||
out_len = MIN(HASH_size(ctx), out_len);
|
||||
memcpy(out, HASH_final(ctx), out_len);
|
||||
return out_len;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,16 @@ ver_params := $(shell echo "$(ver_defs) $(bld_defs)" | $(CPP) $(CPPFLAGS) -P \
|
||||
ver_str := $(shell printf "%s%s %d_%d" $(ver_params))
|
||||
CPPFLAGS+= -DGC_REVISION="$(ver_str)"
|
||||
|
||||
ifeq ($(CONFIG_DCRYPTO),y)
|
||||
INCLUDE_ROOT := $(abspath ./include)
|
||||
CRYPTOCLIB := $(realpath ../../third_party/cryptoc)
|
||||
CPPFLAGS += -I$(abspath .)
|
||||
CPPFLAGS += -I$(abspath ./builtin)
|
||||
CPPFLAGS += -I$(abspath ./chip/$(CHIP))
|
||||
CPPFLAGS += -I$(INCLUDE_ROOT)
|
||||
CPPFLAGS += -I$(CRYPTOCLIB)/include
|
||||
endif
|
||||
|
||||
# Required chip modules
|
||||
chip-y=clock.o gpio.o hwtimer.o jtag.o system.o
|
||||
ifeq ($(CONFIG_POLLING_UART),y)
|
||||
@@ -32,7 +42,6 @@ chip-$(CONFIG_DCRYPTO)+= dcrypto/hmac.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/hkdf.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/p256.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/p256_ec.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/p256_ecdsa.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/p256_ecies.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/rsa.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/sha1.o
|
||||
@@ -96,3 +105,25 @@ $(out)/RW/ec.RW_B.flat: $(out)/util/signer
|
||||
endif
|
||||
|
||||
CR50_RO_KEY ?= rom-testkey-A.pem
|
||||
|
||||
# This file is included twice by the Makefile, once to determine the CHIP info
|
||||
# # and then again after defining all the CONFIG_ and HAS_TASK variables. We use
|
||||
# # a guard so that recipe definitions and variable extensions only happen the
|
||||
# # second time.
|
||||
ifeq ($(CHIP_MK_INCLUDED_ONCE),)
|
||||
CHIP_MK_INCLUDED_ONCE=1
|
||||
else
|
||||
|
||||
ifeq ($(CONFIG_DCRYPTO),y)
|
||||
$(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: LDFLAGS_EXTRA += -L$(out)/cryptoc \
|
||||
-lcryptoc
|
||||
$(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: $(out)/cryptoc/libcryptoc.a
|
||||
|
||||
# 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 \
|
||||
-C $(CRYPTOCLIB)
|
||||
endif # end CONFIG_DCRYPTO
|
||||
|
||||
endif # CHIP_MK_INCLUDED_ONCE is nonempty
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "cryptoc/hmac.h"
|
||||
|
||||
enum cipher_mode {
|
||||
CIPHER_MODE_ECB = 0,
|
||||
CIPHER_MODE_CTR = 1,
|
||||
@@ -26,27 +30,11 @@ enum encrypt_mode {
|
||||
ENCRYPT_MODE = 1
|
||||
};
|
||||
|
||||
struct HASH_CTX; /* Forward declaration. */
|
||||
|
||||
typedef struct HASH_CTX SHA1_CTX;
|
||||
typedef struct HASH_CTX SHA256_CTX;
|
||||
|
||||
enum hashing_mode {
|
||||
HASH_SHA1 = 0,
|
||||
HASH_SHA256 = 1
|
||||
};
|
||||
|
||||
#define DCRYPTO_HASH_update(ctx, data, len) \
|
||||
((ctx)->vtab->update((ctx), (data), (len)))
|
||||
#define DCRYPTO_HASH_final(ctx) \
|
||||
((ctx)->vtab->final((ctx)))
|
||||
#define DCRYPTO_HASH_size(ctx) \
|
||||
((ctx)->vtab->size)
|
||||
|
||||
#define DCRYPTO_SHA1_update(ctx, data, n) \
|
||||
DCRYPTO_HASH_update((ctx), (data), (n))
|
||||
#define DCRYPTO_SHA1_final(ctx) DCRYPTO_HASH_final((ctx))
|
||||
|
||||
/*
|
||||
* AES implementation, based on a hardware AES block.
|
||||
*/
|
||||
@@ -68,16 +56,19 @@ int DCRYPTO_aes_ctr(uint8_t *out, const uint8_t *key, uint32_t key_bits,
|
||||
* is TRUE, in which case there will be no attempt to use the hardware for
|
||||
* this particular hashing session.
|
||||
*/
|
||||
void DCRYPTO_SHA1_init(SHA1_CTX *ctx, uint32_t sw_required);
|
||||
void DCRYPTO_SHA256_init(SHA256_CTX *ctx, uint32_t sw_required);
|
||||
const uint8_t *DCRYPTO_SHA1_hash(const uint8_t *data, uint32_t n,
|
||||
void DCRYPTO_SHA1_init(SHA_CTX *ctx, uint32_t sw_required);
|
||||
void DCRYPTO_SHA256_init(LITE_SHA256_CTX *ctx, uint32_t sw_required);
|
||||
const uint8_t *DCRYPTO_SHA1_hash(const void *data, uint32_t n,
|
||||
uint8_t *digest);
|
||||
const uint8_t *DCRYPTO_SHA256_hash(const void *data, uint32_t n,
|
||||
uint8_t *digest);
|
||||
|
||||
#define DCRYPTO_SHA256_update(ctx, data, n) \
|
||||
DCRYPTO_HASH_update((ctx), (data), (n))
|
||||
#define DCRYPTO_SHA256_final(ctx) DCRYPTO_HASH_final((ctx))
|
||||
const uint8_t *DCRYPTO_SHA256_hash(const uint8_t *data, uint32_t n,
|
||||
uint8_t *digest);
|
||||
/*
|
||||
* HMAC.
|
||||
*/
|
||||
void DCRYPTO_HMAC_SHA256_init(LITE_HMAC_CTX *ctx, const void *key,
|
||||
unsigned int len);
|
||||
const uint8_t *DCRYPTO_HMAC_final(LITE_HMAC_CTX *ctx);
|
||||
|
||||
/*
|
||||
* BIGNUM utility methods.
|
||||
@@ -137,7 +128,6 @@ int DCRYPTO_rsa_key_compute(struct BIGNUM *N, struct BIGNUM *d,
|
||||
/*
|
||||
* EC.
|
||||
*/
|
||||
int DCRYPTO_p256_valid_point(const p256_int *x, const p256_int *y);
|
||||
int DCRYPTO_p256_base_point_mul(p256_int *out_x, p256_int *out_y,
|
||||
const p256_int *n);
|
||||
int DCRYPTO_p256_point_mul(p256_int *out_x, p256_int *out_y,
|
||||
@@ -145,12 +135,6 @@ int DCRYPTO_p256_point_mul(p256_int *out_x, p256_int *out_y,
|
||||
const p256_int *in_y);
|
||||
int DCRYPTO_p256_key_from_bytes(p256_int *x, p256_int *y, p256_int *d,
|
||||
const uint8_t key_bytes[P256_NBYTES]);
|
||||
|
||||
void DCRYPTO_p256_ecdsa_sign(const p256_int *d, const p256_int *digest,
|
||||
p256_int *r, p256_int *s);
|
||||
int DCRYPTO_p256_ecdsa_verify(const p256_int *key_x, const p256_int *key_y,
|
||||
const p256_int *digest, const p256_int *r,
|
||||
const p256_int *s);
|
||||
/* P256 based integration encryption (DH+AES128+SHA256). */
|
||||
/* Authenticated data may be provided, where the first auth_data_len
|
||||
* bytes of in will be authenticated but not encrypted. */
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
#include "dcrypto.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include "cryptoc/sha256.h"
|
||||
|
||||
static int hkdf_extract(uint8_t *PRK, const uint8_t *salt, size_t salt_len,
|
||||
const uint8_t *IKM, size_t IKM_len)
|
||||
{
|
||||
struct HMAC_CTX ctx;
|
||||
LITE_HMAC_CTX ctx;
|
||||
|
||||
if (PRK == NULL)
|
||||
return 0;
|
||||
@@ -19,9 +21,9 @@ static int hkdf_extract(uint8_t *PRK, const uint8_t *salt, size_t salt_len,
|
||||
if (IKM == NULL && IKM_len > 0)
|
||||
return 0;
|
||||
|
||||
dcrypto_HMAC_SHA256_init(&ctx, salt, salt_len);
|
||||
dcrypto_HMAC_update(&ctx, IKM, IKM_len);
|
||||
memcpy(PRK, dcrypto_HMAC_final(&ctx), SHA256_DIGEST_BYTES);
|
||||
DCRYPTO_HMAC_SHA256_init(&ctx, salt, salt_len);
|
||||
HASH_update(&ctx.hash, IKM, IKM_len);
|
||||
memcpy(PRK, DCRYPTO_HMAC_final(&ctx), SHA256_DIGEST_SIZE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -31,8 +33,8 @@ static int hkdf_expand(uint8_t *OKM, size_t OKM_len, const uint8_t *PRK,
|
||||
uint8_t count = 1;
|
||||
const uint8_t *T = OKM;
|
||||
size_t T_len = 0;
|
||||
uint32_t num_blocks = (OKM_len / SHA256_DIGEST_BYTES) +
|
||||
(OKM_len % SHA256_DIGEST_BYTES ? 1 : 0);
|
||||
uint32_t num_blocks = (OKM_len / SHA256_DIGEST_SIZE) +
|
||||
(OKM_len % SHA256_DIGEST_SIZE ? 1 : 0);
|
||||
|
||||
if (OKM == NULL || OKM_len == 0)
|
||||
return 0;
|
||||
@@ -44,17 +46,18 @@ static int hkdf_expand(uint8_t *OKM, size_t OKM_len, const uint8_t *PRK,
|
||||
return 0;
|
||||
|
||||
while (OKM_len > 0) {
|
||||
struct HMAC_CTX ctx;
|
||||
const size_t block_size = MIN(OKM_len, SHA256_DIGEST_BYTES);
|
||||
LITE_HMAC_CTX ctx;
|
||||
const size_t block_size = OKM_len < SHA256_DIGEST_SIZE ?
|
||||
OKM_len : SHA256_DIGEST_SIZE;
|
||||
|
||||
dcrypto_HMAC_SHA256_init(&ctx, PRK, SHA256_DIGEST_BYTES);
|
||||
dcrypto_HMAC_update(&ctx, T, T_len);
|
||||
dcrypto_HMAC_update(&ctx, info, info_len);
|
||||
dcrypto_HMAC_update(&ctx, &count, sizeof(count));
|
||||
memcpy(OKM, dcrypto_HMAC_final(&ctx), block_size);
|
||||
DCRYPTO_HMAC_SHA256_init(&ctx, PRK, SHA256_DIGEST_SIZE);
|
||||
HASH_update(&ctx.hash, T, T_len);
|
||||
HASH_update(&ctx.hash, info, info_len);
|
||||
HASH_update(&ctx.hash, &count, sizeof(count));
|
||||
memcpy(OKM, DCRYPTO_HMAC_final(&ctx), block_size);
|
||||
|
||||
T += T_len;
|
||||
T_len = SHA256_DIGEST_BYTES;
|
||||
T_len = SHA256_DIGEST_SIZE;
|
||||
count += 1;
|
||||
OKM += block_size;
|
||||
OKM_len -= block_size;
|
||||
@@ -68,7 +71,7 @@ int DCRYPTO_hkdf(uint8_t *OKM, size_t OKM_len,
|
||||
const uint8_t *info, size_t info_len)
|
||||
{
|
||||
int result;
|
||||
uint8_t PRK[SHA256_DIGEST_BYTES];
|
||||
uint8_t PRK[SHA256_DIGEST_SIZE];
|
||||
|
||||
if (!hkdf_extract(PRK, salt, salt_len, IKM, IKM_len))
|
||||
return 0;
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "dcrypto.h"
|
||||
|
||||
static void HMAC_init(struct HMAC_CTX *ctx, const void *key, unsigned int len)
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cryptoc/sha256.h"
|
||||
|
||||
/* TODO(ngm): add support for hardware hmac. */
|
||||
static void HMAC_init(LITE_HMAC_CTX *ctx, const void *key, unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@@ -16,9 +19,9 @@ static void HMAC_init(struct HMAC_CTX *ctx, const void *key, unsigned int len)
|
||||
|
||||
if (len > sizeof(ctx->opad)) {
|
||||
DCRYPTO_SHA256_init(&ctx->hash, 0);
|
||||
DCRYPTO_HASH_update(&ctx->hash, key, len);
|
||||
memcpy(&ctx->opad[0], DCRYPTO_HASH_final(&ctx->hash),
|
||||
DCRYPTO_HASH_size(&ctx->hash));
|
||||
HASH_update(&ctx->hash, key, len);
|
||||
memcpy(&ctx->opad[0], HASH_final(&ctx->hash),
|
||||
HASH_size(&ctx->hash));
|
||||
} else {
|
||||
memcpy(&ctx->opad[0], key, len);
|
||||
}
|
||||
@@ -28,29 +31,29 @@ static void HMAC_init(struct HMAC_CTX *ctx, const void *key, unsigned int len)
|
||||
|
||||
DCRYPTO_SHA256_init(&ctx->hash, 0);
|
||||
/* hash ipad */
|
||||
DCRYPTO_HASH_update(&ctx->hash, ctx->opad, sizeof(ctx->opad));
|
||||
HASH_update(&ctx->hash, ctx->opad, sizeof(ctx->opad));
|
||||
|
||||
for (i = 0; i < sizeof(ctx->opad); ++i)
|
||||
ctx->opad[i] ^= (0x36 ^ 0x5c);
|
||||
}
|
||||
|
||||
void dcrypto_HMAC_SHA256_init(struct HMAC_CTX *ctx, const void *key,
|
||||
void DCRYPTO_HMAC_SHA256_init(LITE_HMAC_CTX *ctx, const void *key,
|
||||
unsigned int len)
|
||||
{
|
||||
DCRYPTO_SHA256_init(&ctx->hash, 0);
|
||||
HMAC_init(ctx, key, len);
|
||||
}
|
||||
|
||||
const uint8_t *dcrypto_HMAC_final(struct HMAC_CTX *ctx)
|
||||
const uint8_t *DCRYPTO_HMAC_final(LITE_HMAC_CTX *ctx)
|
||||
{
|
||||
uint8_t digest[SHA_DIGEST_MAX_BYTES]; /* upto SHA2 */
|
||||
|
||||
memcpy(digest, DCRYPTO_HASH_final(&ctx->hash),
|
||||
(DCRYPTO_HASH_size(&ctx->hash) <= sizeof(digest) ?
|
||||
DCRYPTO_HASH_size(&ctx->hash) : sizeof(digest)));
|
||||
memcpy(digest, HASH_final(&ctx->hash),
|
||||
(HASH_size(&ctx->hash) <= sizeof(digest) ?
|
||||
HASH_size(&ctx->hash) : sizeof(digest)));
|
||||
DCRYPTO_SHA256_init(&ctx->hash, 0);
|
||||
DCRYPTO_HASH_update(&ctx->hash, ctx->opad, sizeof(ctx->opad));
|
||||
DCRYPTO_HASH_update(&ctx->hash, digest, DCRYPTO_HASH_size(&ctx->hash));
|
||||
HASH_update(&ctx->hash, ctx->opad, sizeof(ctx->opad));
|
||||
HASH_update(&ctx->hash, digest, HASH_size(&ctx->hash));
|
||||
memset(&ctx->opad[0], 0, sizeof(ctx->opad)); /* wipe key */
|
||||
return DCRYPTO_HASH_final(&ctx->hash);
|
||||
return HASH_final(&ctx->hash);
|
||||
}
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
#ifndef __EC_CHIP_G_DCRYPTO_INTERNAL_H
|
||||
#define __EC_CHIP_G_DCRYPTO_INTERNAL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "sha1.h"
|
||||
#include "sha256.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "cryptoc/p256.h"
|
||||
#include "cryptoc/sha.h"
|
||||
#include "cryptoc/sha256.h"
|
||||
|
||||
/*
|
||||
* SHA.
|
||||
@@ -20,43 +24,10 @@
|
||||
#define CTRL_ENCRYPT 1
|
||||
#define CTRL_NO_SOFT_RESET 0
|
||||
|
||||
struct HASH_CTX; /* Forward declaration. */
|
||||
#define SHA_DIGEST_WORDS (SHA_DIGEST_SIZE / sizeof(uint32_t))
|
||||
#define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / sizeof(uint32_t))
|
||||
|
||||
struct HASH_VTAB {
|
||||
void (* const update)(struct HASH_CTX *, const uint8_t *, uint32_t);
|
||||
const uint8_t *(* const final)(struct HASH_CTX *);
|
||||
const uint8_t *(* const hash)(const uint8_t *, uint32_t, uint8_t *);
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
#define SHA1_DIGEST_BYTES 20
|
||||
#define SHA256_DIGEST_BYTES 32
|
||||
#define SHA384_DIGEST_BYTES 48
|
||||
#define SHA512_DIGEST_BYTES 64
|
||||
|
||||
#define SHA1_DIGEST_WORDS (SHA1_DIGEST_BYTES / sizeof(uint32_t))
|
||||
#define SHA256_DIGEST_WORDS (SHA256_DIGEST_BYTES / sizeof(uint32_t))
|
||||
#define SHA384_DIGEST_WORDS (SHA384_DIGEST_BYTES / sizeof(uint32_t))
|
||||
#define SHA512_DIGEST_WORDS (SHA512_DIGEST_BYTES / sizeof(uint32_t))
|
||||
|
||||
#if defined(CONFIG_SHA512)
|
||||
#define SHA_DIGEST_MAX_BYTES SHA512_DIGEST_BYTES
|
||||
#elif defined(CONFIG_SHA384)
|
||||
#define SHA_DIGEST_MAX_BYTES SHA384_DIGEST_BYTES
|
||||
#elif defined(CONFIG_SHA256)
|
||||
#define SHA_DIGEST_MAX_BYTES SHA256_DIGEST_BYTES
|
||||
#elif defined CONFIG_SHA1
|
||||
#define SHA_DIGEST_MAX_BYTES SHA1_DIGEST_BYTES
|
||||
#endif
|
||||
|
||||
struct HASH_CTX {
|
||||
const struct HASH_VTAB *vtab;
|
||||
union {
|
||||
uint8_t buf[SHA_DIGEST_MAX_BYTES];
|
||||
struct sha1_ctx sw_sha1;
|
||||
struct sha256_ctx sw_sha256;
|
||||
} u;
|
||||
};
|
||||
#define SHA_DIGEST_MAX_BYTES SHA256_DIGEST_SIZE
|
||||
|
||||
enum sha_mode {
|
||||
SHA1_MODE = 0,
|
||||
@@ -79,24 +50,9 @@ void dcrypto_sha_hash(enum sha_mode mode, const uint8_t *data,
|
||||
uint32_t n, uint8_t *digest);
|
||||
void dcrypto_sha_init(enum sha_mode mode);
|
||||
void dcrypto_sha_update(struct HASH_CTX *unused,
|
||||
const uint8_t *data, uint32_t n);
|
||||
const void *data, uint32_t n);
|
||||
void dcrypto_sha_wait(enum sha_mode mode, uint32_t *digest);
|
||||
|
||||
/*
|
||||
* HMAC.
|
||||
*/
|
||||
struct HMAC_CTX {
|
||||
struct HASH_CTX hash;
|
||||
uint8_t opad[64];
|
||||
};
|
||||
|
||||
#define HASH_update(ctx, data, len) \
|
||||
((ctx)->vtab->update((ctx), (data), (len)))
|
||||
void dcrypto_HMAC_SHA256_init(struct HMAC_CTX *ctx, const void *key,
|
||||
unsigned int len);
|
||||
#define dcrypto_HMAC_update(ctx, data, len) HASH_update(&(ctx)->hash, data, len)
|
||||
const uint8_t *dcrypto_HMAC_final(struct HMAC_CTX *ctx);
|
||||
|
||||
/*
|
||||
* BIGNUM.
|
||||
*/
|
||||
@@ -122,54 +78,6 @@ void bn_mul(struct BIGNUM *c, const struct BIGNUM *a, const struct BIGNUM *b);
|
||||
int bn_modinv_vartime(struct BIGNUM *r, const struct BIGNUM *e,
|
||||
const struct BIGNUM *MOD);
|
||||
|
||||
/*
|
||||
* EC.
|
||||
*/
|
||||
#define P256_BITSPERDIGIT 32
|
||||
#define P256_NDIGITS 8
|
||||
#define P256_NBYTES 32
|
||||
|
||||
typedef uint32_t p256_digit;
|
||||
typedef int32_t p256_sdigit;
|
||||
typedef uint64_t p256_ddigit;
|
||||
typedef int64_t p256_sddigit;
|
||||
|
||||
/* Define p256_int as a struct to leverage struct assignment. */
|
||||
typedef struct {
|
||||
p256_digit a[P256_NDIGITS] __packed;
|
||||
} p256_int;
|
||||
|
||||
#define P256_DIGITS(x) ((x)->a)
|
||||
#define P256_DIGIT(x, y) ((x)->a[y])
|
||||
|
||||
#define P256_ZERO { {0} }
|
||||
#define P256_ONE { {1} }
|
||||
|
||||
/* Curve constants. */
|
||||
extern const p256_int SECP256r1_n;
|
||||
extern const p256_int SECP256r1_p;
|
||||
extern const p256_int SECP256r1_b;
|
||||
|
||||
void p256_init(p256_int *a);
|
||||
void p256_from_bin(const uint8_t src[P256_NBYTES], p256_int *dst);
|
||||
void p256_to_bin(const p256_int *src, uint8_t dst[P256_NBYTES]);
|
||||
#define p256_clear(a) p256_init((a))
|
||||
int p256_is_zero(const p256_int *a);
|
||||
int p256_cmp(const p256_int *a, const p256_int *b);
|
||||
int p256_get_bit(const p256_int *scalar, int bit);
|
||||
p256_digit p256_shl(const p256_int *a, int n, p256_int *b);
|
||||
void p256_shr(const p256_int *a, int n, p256_int *b);
|
||||
int p256_add(const p256_int *a, const p256_int *b, p256_int *c);
|
||||
int p256_add_d(const p256_int *a, p256_digit d, p256_int *b);
|
||||
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);
|
||||
void p256_mod(const p256_int *MOD, const p256_int *in, p256_int *out);
|
||||
void p256_modmul(const p256_int *MOD, const p256_int *a,
|
||||
const p256_digit top_b, const p256_int *b, p256_int *c);
|
||||
void p256_modinv(const p256_int *MOD, const p256_int *a, p256_int *b);
|
||||
void p256_modinv_vartime(const p256_int *MOD, const p256_int *a, p256_int *b);
|
||||
|
||||
/*
|
||||
* Utility functions.
|
||||
*/
|
||||
|
||||
@@ -4,442 +4,11 @@
|
||||
*/
|
||||
|
||||
#include "dcrypto.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include "cryptoc/p256.h"
|
||||
|
||||
const p256_int SECP256r1_n = /* curve order */
|
||||
{ {0xfc632551, 0xf3b9cac2, 0xa7179e84, 0xbce6faad, -1, -1, 0, -1} };
|
||||
static const p256_int SECP256r1_nMin2 = /* curve order - 2 */
|
||||
{ {0xfc632551 - 2, 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} };
|
||||
static const p256_int p256_one = P256_ONE;
|
||||
|
||||
void p256_init(p256_int *a)
|
||||
{
|
||||
memset(a, 0, sizeof(*a));
|
||||
}
|
||||
|
||||
int p256_get_bit(const p256_int *scalar, int bit)
|
||||
{
|
||||
return (P256_DIGIT(scalar, bit / P256_BITSPERDIGIT)
|
||||
>> (bit & (P256_BITSPERDIGIT - 1))) & 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_BITSPERDIGIT - n);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* top, c[] += a[] * b */
|
||||
/* Returns new top. */
|
||||
static p256_digit p256_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 p256_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 p256_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;
|
||||
}
|
||||
|
||||
/* top, c[] -= MOD[] & mask (0 or -1) */
|
||||
/* returns new top. */
|
||||
static p256_digit p256_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;
|
||||
}
|
||||
|
||||
/* Convert in. */
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert out. */
|
||||
void p256_to_bin(const p256_int *src, uint8_t dst[P256_NBYTES])
|
||||
{
|
||||
int i;
|
||||
uint8_t *p = &dst[0];
|
||||
|
||||
for (i = P256_NDIGITS - 1; i >= 0; --i) {
|
||||
p256_digit d = P256_DIGIT(src, i);
|
||||
|
||||
p[0] = (d >> 24) & 0xFF;
|
||||
p[1] = (d >> 16) & 0xFF;
|
||||
p[2] = (d >> 8) & 0xFF;
|
||||
p[3] = d & 0xFF;
|
||||
p += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void p256_mod(const p256_int *MOD, const p256_int *in, p256_int *out)
|
||||
{
|
||||
if (out != in)
|
||||
*out = *in;
|
||||
p256_addM(MOD, 0, P256_DIGITS(out),
|
||||
p256_subM(MOD, 0, P256_DIGITS(out), -1));
|
||||
}
|
||||
|
||||
|
||||
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 = p256_muladd(a, P256_DIGIT(b, i), 0, tmp + i);
|
||||
}
|
||||
|
||||
/* Multiply/add top digit. */
|
||||
tmp[i + P256_NDIGITS - 1] = top;
|
||||
top = p256_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 = p256_muladd(MOD, top, 0, reducer);
|
||||
|
||||
/* Subtract reducer from top | tmp. */
|
||||
top = p256_subtop(top_reducer, reducer, top, tmp + i);
|
||||
|
||||
/* top is now either 0 or 1. Make it 0, fixed-timing. */
|
||||
assert(top <= 1);
|
||||
|
||||
top = p256_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. */
|
||||
p256_addM(MOD, 0, tmp, p256_subM(MOD, 0, tmp, -1));
|
||||
|
||||
memcpy(c, tmp, P256_NBYTES);
|
||||
}
|
||||
|
||||
/* if (mask) dst = src, fixed-timing style. */
|
||||
static void conditional_copy(const p256_int *src, p256_int *dst, int mask)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < P256_NDIGITS; ++i) {
|
||||
p256_digit b = P256_DIGIT(src, i) & mask; /* 0 or src[i] */
|
||||
|
||||
b |= P256_DIGIT(dst, i) & ~mask; /* dst[i] or 0 */
|
||||
P256_DIGIT(dst, i) = b;
|
||||
}
|
||||
}
|
||||
|
||||
/* -1 iff (x & 15) == 0, 0 otherwise. */
|
||||
/* Relies on arithmetic shift right behavior. */
|
||||
#define ZEROtoONES(x) (((int32_t)(((x) & 15) - 1)) >> 31)
|
||||
|
||||
/* tbl[0] = tbl[idx], fixed-timing style. */
|
||||
static void set0ToIdx(p256_int tbl[16], int idx)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
tbl[0] = p256_one;
|
||||
for (i = 1; i < 16; ++i)
|
||||
conditional_copy(&tbl[i], &tbl[0], ZEROtoONES(i - idx));
|
||||
}
|
||||
|
||||
/* b = 1/a mod MOD, fixed timing, Fermat's little theorem. */
|
||||
void p256_modinv(const p256_int *MOD, const p256_int *a, p256_int *b)
|
||||
{
|
||||
int i;
|
||||
p256_int tbl[16];
|
||||
|
||||
/* tbl[i] = a**i, tbl[0] unused. */
|
||||
tbl[1] = *a;
|
||||
for (i = 2; i < 16; ++i)
|
||||
p256_modmul(MOD, &tbl[i-1], 0, a, &tbl[i]);
|
||||
|
||||
*b = p256_one;
|
||||
for (i = 256; i > 0; i -= 4) {
|
||||
int32_t idx = 0;
|
||||
|
||||
p256_modmul(MOD, b, 0, b, b);
|
||||
p256_modmul(MOD, b, 0, b, b);
|
||||
p256_modmul(MOD, b, 0, b, b);
|
||||
p256_modmul(MOD, b, 0, b, b);
|
||||
idx |= p256_get_bit(&SECP256r1_nMin2, i - 1) << 3;
|
||||
idx |= p256_get_bit(&SECP256r1_nMin2, i - 2) << 2;
|
||||
idx |= p256_get_bit(&SECP256r1_nMin2, i - 3) << 1;
|
||||
idx |= p256_get_bit(&SECP256r1_nMin2, i - 4) << 0;
|
||||
set0ToIdx(tbl, idx); /* tbl[0] = tbl[idx] */
|
||||
p256_modmul(MOD, b, 0, &tbl[0], &tbl[0]);
|
||||
conditional_copy(&tbl[0], b, ~ZEROtoONES(idx));
|
||||
}
|
||||
}
|
||||
|
||||
static int p256_is_even(const p256_int *a)
|
||||
{
|
||||
return !(P256_DIGIT(a, 0) & 1);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
int DCRYPTO_p256_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);
|
||||
if (p256_sub(&x3, &SECP256r1_p, &x3)) /* make sure 0 <= x3 < p */
|
||||
p256_add(&x3, &SECP256r1_p, &x3);
|
||||
|
||||
return p256_cmp(&y2, &x3) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Key selection based on FIPS-186-4, section B.4.2 (Key Pair
|
||||
* Generation by Testing Candidates).
|
||||
@@ -447,15 +16,13 @@ int DCRYPTO_p256_valid_point(const p256_int *x, const p256_int *y)
|
||||
int DCRYPTO_p256_key_from_bytes(p256_int *x, p256_int *y, p256_int *d,
|
||||
const uint8_t key_bytes[P256_NBYTES])
|
||||
{
|
||||
int valid;
|
||||
p256_int key;
|
||||
|
||||
p256_from_bin(key_bytes, &key);
|
||||
if (p256_cmp(&SECP256r1_nMin2, &key) < 0)
|
||||
return 0;
|
||||
p256_add(&key, &p256_one, &key);
|
||||
valid = DCRYPTO_p256_base_point_mul(x, y, &key);
|
||||
if (valid)
|
||||
*d = key;
|
||||
return valid;
|
||||
p256_add(&key, &p256_one, d);
|
||||
p256_base_point_mul(d, x, y);
|
||||
dcrypto_memset(&key, 0, sizeof(key));
|
||||
return 1;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,103 +0,0 @@
|
||||
/* Copyright 2015 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 <stdint.h>
|
||||
|
||||
#include "dcrypto.h"
|
||||
|
||||
/* Compute k based on a given {key, digest} pair, 0 < k < n. */
|
||||
static void determine_k(const p256_int *key, const p256_int *digest,
|
||||
char *tweak, p256_int *k)
|
||||
{
|
||||
do {
|
||||
p256_int p1, p2;
|
||||
struct HMAC_CTX hmac;
|
||||
|
||||
/* NOTE: taking the p256_int in-memory representation
|
||||
* is not endian neutral. Signatures with an
|
||||
* identical key on identical digests will differ per
|
||||
* host endianness. This however does not jeopardize
|
||||
* the key bits. */
|
||||
dcrypto_HMAC_SHA256_init(&hmac, key, P256_NBYTES);
|
||||
dcrypto_HMAC_update(&hmac, tweak, 1);
|
||||
dcrypto_HMAC_update(&hmac, (uint8_t *) digest, P256_NBYTES);
|
||||
++(*tweak);
|
||||
p256_from_bin(dcrypto_HMAC_final(&hmac), &p1);
|
||||
|
||||
dcrypto_HMAC_SHA256_init(&hmac, key, P256_NBYTES);
|
||||
dcrypto_HMAC_update(&hmac, tweak, 1);
|
||||
dcrypto_HMAC_update(&hmac, (uint8_t *) digest, P256_NBYTES);
|
||||
++(*tweak);
|
||||
p256_from_bin(dcrypto_HMAC_final(&hmac), &p2);
|
||||
|
||||
/* Combine p1 and p2 into well distributed k. */
|
||||
p256_modmul(&SECP256r1_n, &p1, 0, &p2, k);
|
||||
|
||||
/* (Attempt to) clear stack state. */
|
||||
p256_clear(&p1);
|
||||
p256_clear(&p2);
|
||||
|
||||
} while (p256_is_zero(k));
|
||||
}
|
||||
|
||||
void DCRYPTO_p256_ecdsa_sign(const p256_int *key, const p256_int *digest,
|
||||
p256_int *r, p256_int *s)
|
||||
{
|
||||
char tweak = 'A';
|
||||
p256_digit top;
|
||||
|
||||
for (;;) {
|
||||
p256_int k, kinv;
|
||||
|
||||
determine_k(key, digest, &tweak, &k);
|
||||
DCRYPTO_p256_base_point_mul(r, s, &k);
|
||||
p256_mod(&SECP256r1_n, r, r);
|
||||
|
||||
/* Make sure r != 0. */
|
||||
if (p256_is_zero(r))
|
||||
continue;
|
||||
|
||||
p256_modmul(&SECP256r1_n, r, 0, key, s);
|
||||
top = p256_add(s, digest, s);
|
||||
p256_modinv(&SECP256r1_n, &k, &kinv);
|
||||
p256_modmul(&SECP256r1_n, &kinv, top, s, s);
|
||||
|
||||
/* (Attempt to) clear stack state. */
|
||||
p256_clear(&k);
|
||||
p256_clear(&kinv);
|
||||
|
||||
/* Make sure s != 0. */
|
||||
if (p256_is_zero(s))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int DCRYPTO_p256_ecdsa_verify(const p256_int *key_x, const p256_int *key_y,
|
||||
const p256_int *digest,
|
||||
const p256_int *r, const p256_int *s)
|
||||
{
|
||||
p256_int u, v;
|
||||
|
||||
/* Check public key. */
|
||||
if (!DCRYPTO_p256_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, digest, 0, &v, &u); /* digest / 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;
|
||||
}
|
||||
@@ -7,6 +7,10 @@
|
||||
#include "dcrypto.h"
|
||||
|
||||
#include "trng.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "cryptoc/p256.h"
|
||||
#include "cryptoc/sha256.h"
|
||||
|
||||
#define AES_KEY_BYTES 16
|
||||
#define HMAC_KEY_BYTES 32
|
||||
@@ -35,14 +39,14 @@ size_t DCRYPTO_ecies_encrypt(
|
||||
uint8_t key[AES_KEY_BYTES + HMAC_KEY_BYTES];
|
||||
const uint8_t *aes_key;
|
||||
const uint8_t *hmac_key;
|
||||
struct HMAC_CTX ctx;
|
||||
LITE_HMAC_CTX ctx;
|
||||
uint8_t *outp = out;
|
||||
uint8_t *ciphertext;
|
||||
|
||||
if (auth_data_len > in_len)
|
||||
return 0;
|
||||
if (out_len < 1 + P256_NBYTES + P256_NBYTES +
|
||||
in_len + SHA256_DIGEST_BYTES)
|
||||
in_len + SHA256_DIGEST_SIZE)
|
||||
return 0;
|
||||
|
||||
/* Generate emphemeral EC key. */
|
||||
@@ -54,7 +58,7 @@ size_t DCRYPTO_ecies_encrypt(
|
||||
&eph_d, pub_x, pub_y))
|
||||
return 0;
|
||||
/* Check for computational errors. */
|
||||
if (!DCRYPTO_p256_valid_point(&secret_x, &secret_y))
|
||||
if (!p256_is_valid_point(&secret_x, &secret_y))
|
||||
return 0;
|
||||
/* Convert secret to big-endian. */
|
||||
reverse(&secret_x, sizeof(secret_x));
|
||||
@@ -94,11 +98,11 @@ size_t DCRYPTO_ecies_encrypt(
|
||||
outp += P256_NBYTES;
|
||||
|
||||
/* Calculate HMAC(auth_data || ciphertext). */
|
||||
dcrypto_HMAC_SHA256_init(&ctx, hmac_key, HMAC_KEY_BYTES);
|
||||
dcrypto_HMAC_update(&ctx, outp, in_len);
|
||||
DCRYPTO_HMAC_SHA256_init(&ctx, hmac_key, HMAC_KEY_BYTES);
|
||||
HASH_update(&ctx.hash, outp, in_len);
|
||||
outp += in_len;
|
||||
memcpy(outp, dcrypto_HMAC_final(&ctx), SHA256_DIGEST_BYTES);
|
||||
outp += SHA256_DIGEST_BYTES;
|
||||
memcpy(outp, DCRYPTO_HMAC_final(&ctx), SHA256_DIGEST_SIZE);
|
||||
outp += SHA256_DIGEST_SIZE;
|
||||
|
||||
return outp - (uint8_t *) out;
|
||||
}
|
||||
@@ -117,17 +121,17 @@ size_t DCRYPTO_ecies_decrypt(
|
||||
uint8_t key[AES_KEY_BYTES + HMAC_KEY_BYTES];
|
||||
const uint8_t *aes_key;
|
||||
const uint8_t *hmac_key;
|
||||
struct HMAC_CTX ctx;
|
||||
LITE_HMAC_CTX ctx;
|
||||
const uint8_t *inp = in;
|
||||
uint8_t *outp = out;
|
||||
|
||||
if (in_len < 1 + P256_NBYTES + P256_NBYTES + auth_data_len +
|
||||
SHA256_DIGEST_BYTES)
|
||||
SHA256_DIGEST_SIZE)
|
||||
return 0;
|
||||
if (inp[0] != 0x04)
|
||||
return 0;
|
||||
|
||||
in_len -= 1 + P256_NBYTES + P256_NBYTES + SHA256_DIGEST_BYTES;
|
||||
in_len -= 1 + P256_NBYTES + P256_NBYTES + SHA256_DIGEST_SIZE;
|
||||
|
||||
inp++;
|
||||
p256_from_bin(inp, &eph_x);
|
||||
@@ -136,14 +140,14 @@ size_t DCRYPTO_ecies_decrypt(
|
||||
inp += P256_NBYTES;
|
||||
|
||||
/* Verify that the public point is on the curve. */
|
||||
if (!DCRYPTO_p256_valid_point(&eph_x, &eph_y))
|
||||
if (!p256_is_valid_point(&eph_x, &eph_y))
|
||||
return 0;
|
||||
/* Compute the DH point. */
|
||||
if (!DCRYPTO_p256_point_mul(&secret_x, &secret_y,
|
||||
d, &eph_x, &eph_y))
|
||||
return 0;
|
||||
/* Check for computational errors. */
|
||||
if (!DCRYPTO_p256_valid_point(&secret_x, &secret_y))
|
||||
if (!p256_is_valid_point(&secret_x, &secret_y))
|
||||
return 0;
|
||||
/* Convert secret to big-endian. */
|
||||
reverse(&secret_x, sizeof(secret_x));
|
||||
@@ -155,11 +159,11 @@ size_t DCRYPTO_ecies_decrypt(
|
||||
|
||||
aes_key = &key[0];
|
||||
hmac_key = &key[AES_KEY_BYTES];
|
||||
dcrypto_HMAC_SHA256_init(&ctx, hmac_key, HMAC_KEY_BYTES);
|
||||
dcrypto_HMAC_update(&ctx, inp, in_len);
|
||||
DCRYPTO_HMAC_SHA256_init(&ctx, hmac_key, HMAC_KEY_BYTES);
|
||||
HASH_update(&ctx.hash, inp, in_len);
|
||||
/* TODO(ngm): replace with constant time verify. */
|
||||
if (memcmp(inp + in_len, dcrypto_HMAC_final(&ctx),
|
||||
SHA256_DIGEST_BYTES) != 0)
|
||||
if (memcmp(inp + in_len, DCRYPTO_HMAC_final(&ctx),
|
||||
SHA256_DIGEST_SIZE) != 0)
|
||||
return 0;
|
||||
|
||||
memmove(outp, inp, auth_data_len);
|
||||
|
||||
@@ -11,11 +11,14 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "cryptoc/sha.h"
|
||||
#include "cryptoc/sha256.h"
|
||||
|
||||
static void MGF1_xor(uint8_t *dst, uint32_t dst_len,
|
||||
const uint8_t *seed, uint32_t seed_len,
|
||||
enum hashing_mode hashing)
|
||||
{
|
||||
struct HASH_CTX ctx;
|
||||
HASH_CTX ctx;
|
||||
struct {
|
||||
uint8_t b3;
|
||||
uint8_t b2;
|
||||
@@ -23,8 +26,8 @@ static void MGF1_xor(uint8_t *dst, uint32_t dst_len,
|
||||
uint8_t b0;
|
||||
} cnt;
|
||||
const uint8_t *digest;
|
||||
const size_t hash_size = (hashing == HASH_SHA1) ? SHA1_DIGEST_BYTES
|
||||
: SHA256_DIGEST_BYTES;
|
||||
const size_t hash_size = (hashing == HASH_SHA1) ? SHA_DIGEST_SIZE
|
||||
: SHA256_DIGEST_SIZE;
|
||||
|
||||
cnt.b0 = cnt.b1 = cnt.b2 = cnt.b3 = 0;
|
||||
while (dst_len) {
|
||||
@@ -35,9 +38,9 @@ static void MGF1_xor(uint8_t *dst, uint32_t dst_len,
|
||||
else
|
||||
DCRYPTO_SHA256_init(&ctx, 0);
|
||||
|
||||
DCRYPTO_HASH_update(&ctx, seed, seed_len);
|
||||
DCRYPTO_HASH_update(&ctx, (uint8_t *) &cnt, sizeof(cnt));
|
||||
digest = DCRYPTO_HASH_final(&ctx);
|
||||
HASH_update(&ctx, seed, seed_len);
|
||||
HASH_update(&ctx, (uint8_t *) &cnt, sizeof(cnt));
|
||||
digest = HASH_final(&ctx);
|
||||
for (i = 0; i < dst_len && i < hash_size; ++i)
|
||||
*dst++ ^= *digest++;
|
||||
dst_len -= i;
|
||||
@@ -62,8 +65,8 @@ static int oaep_pad(uint8_t *output, uint32_t output_len,
|
||||
enum hashing_mode hashing, const char *label)
|
||||
{
|
||||
int i;
|
||||
const size_t hash_size = (hashing == HASH_SHA1) ? SHA1_DIGEST_BYTES
|
||||
: SHA256_DIGEST_BYTES;
|
||||
const size_t hash_size = (hashing == HASH_SHA1) ? SHA_DIGEST_SIZE
|
||||
: SHA256_DIGEST_SIZE;
|
||||
uint8_t *const seed = output + 1;
|
||||
uint8_t *const phash = seed + hash_size;
|
||||
uint8_t *const PS = phash + hash_size;
|
||||
@@ -92,8 +95,8 @@ static int oaep_pad(uint8_t *output, uint32_t output_len,
|
||||
else
|
||||
DCRYPTO_SHA256_init(&ctx, 0);
|
||||
|
||||
DCRYPTO_HASH_update(&ctx, label, label ? strlen(label) + 1 : 0);
|
||||
memcpy(phash, DCRYPTO_HASH_final(&ctx), hash_size);
|
||||
HASH_update(&ctx, label, label ? strlen(label) + 1 : 0);
|
||||
memcpy(phash, HASH_final(&ctx), hash_size);
|
||||
*one = 1;
|
||||
memcpy(one + 1, msg, msg_len);
|
||||
MGF1_xor(phash, hash_size + 1 + max_msg_len,
|
||||
@@ -109,8 +112,8 @@ static int check_oaep_pad(uint8_t *out, uint32_t *out_len,
|
||||
uint8_t *padded, uint32_t padded_len,
|
||||
enum hashing_mode hashing, const char *label)
|
||||
{
|
||||
const size_t hash_size = (hashing == HASH_SHA1) ? SHA1_DIGEST_BYTES
|
||||
: SHA256_DIGEST_BYTES;
|
||||
const size_t hash_size = (hashing == HASH_SHA1) ? SHA_DIGEST_SIZE
|
||||
: SHA256_DIGEST_SIZE;
|
||||
uint8_t *seed = padded + 1;
|
||||
uint8_t *phash = seed + hash_size;
|
||||
uint8_t *PS = phash + hash_size;
|
||||
@@ -132,9 +135,9 @@ static int check_oaep_pad(uint8_t *out, uint32_t *out_len,
|
||||
DCRYPTO_SHA1_init(&ctx, 0);
|
||||
else
|
||||
DCRYPTO_SHA256_init(&ctx, 0);
|
||||
DCRYPTO_HASH_update(&ctx, label, label ? strlen(label) + 1 : 0);
|
||||
HASH_update(&ctx, label, label ? strlen(label) + 1 : 0);
|
||||
|
||||
bad = memcmp(phash, DCRYPTO_HASH_final(&ctx), hash_size);
|
||||
bad = memcmp(phash, HASH_final(&ctx), hash_size);
|
||||
bad |= padded[0];
|
||||
|
||||
for (i = PS - padded; i < padded_len; i++) {
|
||||
@@ -239,8 +242,8 @@ static int pkcs1_type1_pad(uint8_t *padded, uint32_t padded_len,
|
||||
: &SHA256_DER[0];
|
||||
const uint32_t der_size = (hashing == HASH_SHA1) ? sizeof(SHA1_DER)
|
||||
: sizeof(SHA256_DER);
|
||||
const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA1_DIGEST_BYTES
|
||||
: SHA256_DIGEST_BYTES;
|
||||
const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA_DIGEST_SIZE
|
||||
: SHA256_DIGEST_SIZE;
|
||||
uint32_t ps_len;
|
||||
|
||||
if (padded_len < RSA_PKCS1_PADDING_SIZE + der_size)
|
||||
@@ -273,8 +276,8 @@ static int check_pkcs1_type1_pad(const uint8_t *msg, uint32_t msg_len,
|
||||
: &SHA256_DER[0];
|
||||
const uint32_t der_size = (hashing == HASH_SHA1) ? sizeof(SHA1_DER)
|
||||
: sizeof(SHA256_DER);
|
||||
const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA1_DIGEST_BYTES
|
||||
: SHA256_DIGEST_BYTES;
|
||||
const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA_DIGEST_SIZE
|
||||
: SHA256_DIGEST_SIZE;
|
||||
uint32_t ps_len;
|
||||
|
||||
if (msg_len != hash_size)
|
||||
@@ -303,8 +306,8 @@ static int pkcs1_pss_pad(uint8_t *padded, uint32_t padded_len,
|
||||
const uint8_t *in, uint32_t in_len,
|
||||
enum hashing_mode hashing)
|
||||
{
|
||||
const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA1_DIGEST_BYTES
|
||||
: SHA256_DIGEST_BYTES;
|
||||
const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA_DIGEST_SIZE
|
||||
: SHA256_DIGEST_SIZE;
|
||||
const uint32_t salt_len = MIN(padded_len - hash_size - 2, hash_size);
|
||||
uint32_t db_len;
|
||||
uint32_t ps_len;
|
||||
@@ -323,14 +326,14 @@ static int pkcs1_pss_pad(uint8_t *padded, uint32_t padded_len,
|
||||
|
||||
/* Pilfer bits of output for temporary use. */
|
||||
memset(padded, 0, 8);
|
||||
DCRYPTO_HASH_update(&ctx, padded, 8);
|
||||
DCRYPTO_HASH_update(&ctx, in, in_len);
|
||||
HASH_update(&ctx, padded, 8);
|
||||
HASH_update(&ctx, in, in_len);
|
||||
/* Pilfer bits of output for temporary use. */
|
||||
rand_bytes(padded, salt_len);
|
||||
DCRYPTO_HASH_update(&ctx, padded, salt_len);
|
||||
HASH_update(&ctx, padded, salt_len);
|
||||
|
||||
/* Output hash. */
|
||||
memcpy(padded + db_len, DCRYPTO_HASH_final(&ctx), hash_size);
|
||||
memcpy(padded + db_len, HASH_final(&ctx), hash_size);
|
||||
|
||||
/* Prepare DB. */
|
||||
ps_len = db_len - salt_len - 1;
|
||||
@@ -351,13 +354,13 @@ static int check_pkcs1_pss_pad(const uint8_t *in, uint32_t in_len,
|
||||
uint8_t *padded, uint32_t padded_len,
|
||||
enum hashing_mode hashing)
|
||||
{
|
||||
const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA1_DIGEST_BYTES
|
||||
: SHA256_DIGEST_BYTES;
|
||||
const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA_DIGEST_SIZE
|
||||
: SHA256_DIGEST_SIZE;
|
||||
const uint8_t zeros[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint32_t db_len;
|
||||
uint32_t max_ps_len;
|
||||
uint32_t salt_len;
|
||||
struct HASH_CTX ctx;
|
||||
HASH_CTX ctx;
|
||||
int bad = 0;
|
||||
int i;
|
||||
|
||||
@@ -392,10 +395,10 @@ static int check_pkcs1_pss_pad(const uint8_t *in, uint32_t in_len,
|
||||
DCRYPTO_SHA1_init(&ctx, 0);
|
||||
else
|
||||
DCRYPTO_SHA256_init(&ctx, 0);
|
||||
DCRYPTO_HASH_update(&ctx, zeros, sizeof(zeros));
|
||||
DCRYPTO_HASH_update(&ctx, in, in_len);
|
||||
DCRYPTO_HASH_update(&ctx, padded + db_len - salt_len, salt_len);
|
||||
bad |= memcmp(padded + db_len, DCRYPTO_HASH_final(&ctx), hash_size);
|
||||
HASH_update(&ctx, zeros, sizeof(zeros));
|
||||
HASH_update(&ctx, in, in_len);
|
||||
HASH_update(&ctx, padded + db_len - salt_len, salt_len);
|
||||
bad |= memcmp(padded + db_len, HASH_final(&ctx), hash_size);
|
||||
return !bad;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,59 +7,29 @@
|
||||
#include "internal.h"
|
||||
#include "registers.h"
|
||||
|
||||
static void sw_sha1_init(SHA1_CTX *ctx);
|
||||
static void sw_sha1_update(SHA1_CTX *ctx, const uint8_t *data, uint32_t len);
|
||||
static const uint8_t *sw_sha1_final(SHA1_CTX *ctx);
|
||||
static const uint8_t *sha1_hash(const uint8_t *data, uint32_t len,
|
||||
uint8_t *digest);
|
||||
static const uint8_t *dcrypto_sha1_final(SHA1_CTX *unused);
|
||||
|
||||
/* Software SHA1 implementation. */
|
||||
static const struct HASH_VTAB SW_SHA1_VTAB = {
|
||||
sw_sha1_update,
|
||||
sw_sha1_final,
|
||||
sha1_hash,
|
||||
SHA1_DIGEST_BYTES
|
||||
};
|
||||
|
||||
static void sw_sha1_init(SHA1_CTX *ctx)
|
||||
{
|
||||
ctx->vtab = &SW_SHA1_VTAB;
|
||||
sha1_init(&ctx->u.sw_sha1);
|
||||
}
|
||||
|
||||
static void sw_sha1_update(SHA1_CTX *ctx, const uint8_t *data, uint32_t len)
|
||||
{
|
||||
sha1_update(&ctx->u.sw_sha1, data, len);
|
||||
}
|
||||
|
||||
static const uint8_t *sw_sha1_final(SHA1_CTX *ctx)
|
||||
{
|
||||
return sha1_final(&ctx->u.sw_sha1);
|
||||
}
|
||||
|
||||
static const uint8_t *sha1_hash(const uint8_t *data, uint32_t len,
|
||||
uint8_t *digest)
|
||||
{
|
||||
SHA1_CTX ctx;
|
||||
|
||||
sw_sha1_init(&ctx);
|
||||
sw_sha1_update(&ctx, data, len);
|
||||
memcpy(digest, sw_sha1_final(&ctx), SHA1_DIGEST_BYTES);
|
||||
return digest;
|
||||
}
|
||||
#include "cryptoc/sha.h"
|
||||
|
||||
static void dcrypto_sha1_init(SHA_CTX *ctx);
|
||||
static const uint8_t *dcrypto_sha1_final(SHA_CTX *unused);
|
||||
|
||||
/*
|
||||
* Hardware SHA implementation.
|
||||
*/
|
||||
static const struct HASH_VTAB HW_SHA1_VTAB = {
|
||||
static const HASH_VTAB HW_SHA1_VTAB = {
|
||||
dcrypto_sha1_init,
|
||||
dcrypto_sha_update,
|
||||
dcrypto_sha1_final,
|
||||
DCRYPTO_SHA1_hash,
|
||||
SHA1_DIGEST_BYTES
|
||||
SHA_DIGEST_SIZE
|
||||
};
|
||||
|
||||
/* Requires dcrypto_grab_sha_hw() to be called first. */
|
||||
static void dcrypto_sha1_init(SHA_CTX *ctx)
|
||||
{
|
||||
ctx->f = &HW_SHA1_VTAB;
|
||||
dcrypto_sha_init(SHA1_MODE);
|
||||
}
|
||||
|
||||
/* Select and initialize either the software or hardware
|
||||
* implementation. If "multi-threaded" behaviour is required, then
|
||||
* callers must set sw_required to 1. This is because SHA1 state
|
||||
@@ -69,30 +39,27 @@ static const struct HASH_VTAB HW_SHA1_VTAB = {
|
||||
* If the caller has no preference as to implementation, then hardware
|
||||
* is preferred based on availability. Hardware is considered to be
|
||||
* in use between init() and finished() calls. */
|
||||
void DCRYPTO_SHA1_init(SHA1_CTX *ctx, uint32_t sw_required)
|
||||
void DCRYPTO_SHA1_init(SHA_CTX *ctx, uint32_t sw_required)
|
||||
{
|
||||
if (!sw_required && dcrypto_grab_sha_hw()) {
|
||||
ctx->vtab = &HW_SHA1_VTAB;
|
||||
dcrypto_sha_init(SHA1_MODE);
|
||||
} else {
|
||||
sw_sha1_init(ctx);
|
||||
}
|
||||
if (!sw_required && dcrypto_grab_sha_hw())
|
||||
dcrypto_sha1_init(ctx);
|
||||
else
|
||||
SHA_init(ctx);
|
||||
}
|
||||
|
||||
static const uint8_t *dcrypto_sha1_final(SHA1_CTX *ctx)
|
||||
static const uint8_t *dcrypto_sha1_final(SHA_CTX *ctx)
|
||||
{
|
||||
dcrypto_sha_wait(SHA1_MODE, (uint32_t *) ctx->u.buf);
|
||||
return ctx->u.buf;
|
||||
dcrypto_sha_wait(SHA1_MODE, (uint32_t *) ctx->buf);
|
||||
return ctx->buf;
|
||||
}
|
||||
|
||||
const uint8_t *DCRYPTO_SHA1_hash(const uint8_t *data, uint32_t n,
|
||||
const uint8_t *DCRYPTO_SHA1_hash(const void *data, uint32_t n,
|
||||
uint8_t *digest)
|
||||
{
|
||||
if (dcrypto_grab_sha_hw())
|
||||
/* dcrypto_sha_wait() will release the hw. */
|
||||
dcrypto_sha_hash(SHA1_MODE, data, n, digest);
|
||||
else
|
||||
sha1_hash(data, n, digest);
|
||||
SHA_hash(data, n, digest);
|
||||
return digest;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
#include "registers.h"
|
||||
#include "util.h"
|
||||
|
||||
static const uint8_t *dcrypto_sha256_final(SHA256_CTX *ctx);
|
||||
#include "cryptoc/sha256.h"
|
||||
|
||||
static void dcrypto_sha256_init(LITE_SHA256_CTX *ctx);
|
||||
static const uint8_t *dcrypto_sha256_final(LITE_SHA256_CTX *ctx);
|
||||
|
||||
#ifdef SECTION_IS_RO
|
||||
/* RO is single threaded. */
|
||||
@@ -25,46 +28,6 @@ static inline void dcrypto_release_sha_hw(void)
|
||||
#include "task.h"
|
||||
static struct mutex hw_busy_mutex;
|
||||
|
||||
static void sha256_init(SHA256_CTX *ctx);
|
||||
static void sha256_update(SHA256_CTX *ctx, const uint8_t *data, uint32_t len);
|
||||
static const uint8_t *sha256_final(SHA256_CTX *ctx);
|
||||
static const uint8_t *sha256_hash(const uint8_t *data, uint32_t len,
|
||||
uint8_t *digest);
|
||||
|
||||
static const struct HASH_VTAB SW_SHA256_VTAB = {
|
||||
sha256_update,
|
||||
sha256_final,
|
||||
sha256_hash,
|
||||
SHA256_DIGEST_BYTES
|
||||
};
|
||||
|
||||
static void sha256_init(SHA256_CTX *ctx)
|
||||
{
|
||||
ctx->vtab = &SW_SHA256_VTAB;
|
||||
SHA256_init(&ctx->u.sw_sha256);
|
||||
}
|
||||
|
||||
static void sha256_update(SHA256_CTX *ctx, const uint8_t *data, uint32_t len)
|
||||
{
|
||||
SHA256_update(&ctx->u.sw_sha256, data, len);
|
||||
}
|
||||
|
||||
static const uint8_t *sha256_final(SHA256_CTX *ctx)
|
||||
{
|
||||
return SHA256_final(&ctx->u.sw_sha256);
|
||||
}
|
||||
|
||||
static const uint8_t *sha256_hash(const uint8_t *data, uint32_t len,
|
||||
uint8_t *digest)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
|
||||
sha256_init(&ctx);
|
||||
sha256_update(&ctx, data, len);
|
||||
memcpy(digest, sha256_final(&ctx), SHA256_DIGEST_BYTES);
|
||||
return digest;
|
||||
}
|
||||
|
||||
static int hw_busy;
|
||||
|
||||
int dcrypto_grab_sha_hw(void)
|
||||
@@ -94,8 +57,8 @@ void dcrypto_sha_wait(enum sha_mode mode, uint32_t *digest)
|
||||
{
|
||||
int i;
|
||||
const int digest_len = (mode == SHA1_MODE) ?
|
||||
SHA1_DIGEST_BYTES :
|
||||
SHA256_DIGEST_BYTES;
|
||||
SHA_DIGEST_SIZE :
|
||||
SHA256_DIGEST_SIZE;
|
||||
|
||||
/* Stop LIVESTREAM mode. */
|
||||
GWRITE_FIELD(KEYMGR, SHA_TRIG, TRIG_STOP, 1);
|
||||
@@ -110,11 +73,12 @@ void dcrypto_sha_wait(enum sha_mode mode, uint32_t *digest)
|
||||
}
|
||||
|
||||
/* Hardware SHA implementation. */
|
||||
static const struct HASH_VTAB HW_SHA256_VTAB = {
|
||||
static const HASH_VTAB HW_SHA256_VTAB = {
|
||||
dcrypto_sha256_init,
|
||||
dcrypto_sha_update,
|
||||
dcrypto_sha256_final,
|
||||
DCRYPTO_SHA256_hash,
|
||||
SHA256_DIGEST_BYTES
|
||||
SHA256_DIGEST_SIZE
|
||||
};
|
||||
|
||||
void dcrypto_sha_hash(enum sha_mode mode, const uint8_t *data, uint32_t n,
|
||||
@@ -126,7 +90,7 @@ void dcrypto_sha_hash(enum sha_mode mode, const uint8_t *data, uint32_t n,
|
||||
}
|
||||
|
||||
void dcrypto_sha_update(struct HASH_CTX *unused,
|
||||
const uint8_t *data, uint32_t n)
|
||||
const void *data, uint32_t n)
|
||||
{
|
||||
const uint8_t *bp = (const uint8_t *) data;
|
||||
const uint32_t *wp;
|
||||
@@ -180,25 +144,30 @@ void dcrypto_sha_init(enum sha_mode mode)
|
||||
GWRITE_FIELD(KEYMGR, SHA_TRIG, TRIG_GO, 1);
|
||||
}
|
||||
|
||||
void DCRYPTO_SHA256_init(SHA256_CTX *ctx, uint32_t sw_required)
|
||||
static void dcrypto_sha256_init(LITE_SHA256_CTX *ctx)
|
||||
{
|
||||
if (!sw_required && dcrypto_grab_sha_hw()) {
|
||||
ctx->vtab = &HW_SHA256_VTAB;
|
||||
dcrypto_sha_init(SHA256_MODE);
|
||||
}
|
||||
ctx->f = &HW_SHA256_VTAB;
|
||||
dcrypto_sha_init(SHA256_MODE);
|
||||
}
|
||||
|
||||
/* Requires dcrypto_grab_sha_hw() to be called first. */
|
||||
void DCRYPTO_SHA256_init(LITE_SHA256_CTX *ctx, uint32_t sw_required)
|
||||
{
|
||||
if (!sw_required && dcrypto_grab_sha_hw())
|
||||
dcrypto_sha256_init(ctx);
|
||||
#ifndef SECTION_IS_RO
|
||||
else
|
||||
sha256_init(ctx);
|
||||
SHA256_init(ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const uint8_t *dcrypto_sha256_final(SHA256_CTX *ctx)
|
||||
static const uint8_t *dcrypto_sha256_final(LITE_SHA256_CTX *ctx)
|
||||
{
|
||||
dcrypto_sha_wait(SHA256_MODE, (uint32_t *) ctx->u.buf);
|
||||
return ctx->u.buf;
|
||||
dcrypto_sha_wait(SHA256_MODE, (uint32_t *) ctx->buf);
|
||||
return ctx->buf;
|
||||
}
|
||||
|
||||
const uint8_t *DCRYPTO_SHA256_hash(const uint8_t *data, uint32_t n,
|
||||
const uint8_t *DCRYPTO_SHA256_hash(const void *data, uint32_t n,
|
||||
uint8_t *digest)
|
||||
{
|
||||
if (dcrypto_grab_sha_hw())
|
||||
@@ -206,7 +175,7 @@ const uint8_t *DCRYPTO_SHA256_hash(const uint8_t *data, uint32_t n,
|
||||
dcrypto_sha_hash(SHA256_MODE, data, n, digest);
|
||||
#ifndef SECTION_IS_RO
|
||||
else
|
||||
sha256_hash(data, n, digest);
|
||||
SHA256_hash(data, n, digest);
|
||||
#endif
|
||||
return digest;
|
||||
}
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
#include "hooks.h"
|
||||
#include "include/compile_time_macros.h"
|
||||
#include "memory.h"
|
||||
#include "sha1.h"
|
||||
#include "uart.h"
|
||||
|
||||
#include "cryptoc/sha.h"
|
||||
|
||||
#define CPRINTF(format, args...) cprintf(CC_EXTENSION, format, ## args)
|
||||
|
||||
/* Various upgrade extension command return values. */
|
||||
@@ -91,7 +92,7 @@ void fw_upgrade_command_handler(void *body,
|
||||
{
|
||||
struct upgrade_command *cmd_body = body;
|
||||
uint8_t *rv = body;
|
||||
uint8_t sha1_digest[SHA1_DIGEST_SIZE];
|
||||
uint8_t sha1_digest[SHA_DIGEST_SIZE];
|
||||
size_t body_size;
|
||||
uint32_t block_offset;
|
||||
|
||||
|
||||
@@ -1566,8 +1566,6 @@
|
||||
|
||||
/* Support computing of other hash sizes (without the VBOOT code) */
|
||||
#undef CONFIG_SHA256
|
||||
#undef CONFIG_SHA384
|
||||
#undef CONFIG_SHA512
|
||||
|
||||
/* Emulate the CLZ (Count Leading Zeros) in software for CPU lacking support */
|
||||
#undef CONFIG_SOFTWARE_CLZ
|
||||
|
||||
Reference in New Issue
Block a user