Files
OpenCellular/chip/g/dcrypto/internal.h
Vincent Palatin e9a007d0e1 g: use deterministic k for individual attestation certificate ECDSA
Implement the RFC 6979 to get a deterministic integer k when doing the
ECDSA signing of the x.509 certificates used by U2F and particularly
individual attestation mechanism, rather than using the random generator
as per the original ECDSA algorithm.
So the generated certs have bit-for-bit identical signatures when the
content is identical.

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>

BRANCH=cr50
BUG=b:35545754
TEST=pass U2FTest and manually dump several individual attestation certs,
run the "rfc6779" console command when enabled.

Change-Id: I7b73eee6d5a863aae9a7eec49db884151bad5ab4
Reviewed-on: https://chromium-review.googlesource.com/558073
Commit-Ready: Vadim Bendebury <vbendeb@chromium.org>
Tested-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-by: Marius Schilder <mschilder@chromium.org>
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
2017-08-03 19:23:22 -07:00

178 lines
5.2 KiB
C

/* 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.
*/
#ifndef __EC_CHIP_G_DCRYPTO_INTERNAL_H
#define __EC_CHIP_G_DCRYPTO_INTERNAL_H
#include <stddef.h>
#include <string.h>
#include "common.h"
#include "util.h"
#include "cryptoc/p256.h"
#include "cryptoc/sha.h"
#include "cryptoc/sha256.h"
#include "cryptoc/sha384.h"
#include "cryptoc/sha512.h"
/*
* SHA.
*/
#define CTRL_CTR_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#define CTRL_ENABLE 1
#define CTRL_ENCRYPT 1
#define CTRL_NO_SOFT_RESET 0
#define SHA_DIGEST_WORDS (SHA_DIGEST_SIZE / sizeof(uint32_t))
#define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / sizeof(uint32_t))
#ifdef SHA512_SUPPORT
#define SHA_DIGEST_MAX_BYTES SHA512_DIGEST_SIZE
#else
#define SHA_DIGEST_MAX_BYTES SHA256_DIGEST_SIZE
#endif
enum sha_mode {
SHA1_MODE = 0,
SHA256_MODE = 1
};
/*
* Use this structure to avoid alignment problems with input and output
* pointers.
*/
struct access_helper {
uint32_t udata;
} __packed;
#ifndef SECTION_IS_RO
int dcrypto_grab_sha_hw(void);
void dcrypto_release_sha_hw(void);
#endif
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 void *data, uint32_t n);
void dcrypto_sha_wait(enum sha_mode mode, uint32_t *digest);
/*
* BIGNUM.
*/
#define LITE_BN_BITS2 32
#define LITE_BN_BYTES 4
struct LITE_BIGNUM {
uint32_t dmax; /* Size of d, in 32-bit words. */
struct access_helper *d; /* Word array, little endian format ... */
};
#define BN_DIGIT(b, i) ((b)->d[(i)].udata)
void bn_init(struct LITE_BIGNUM *bn, void *buf, size_t len);
#define bn_size(b) ((b)->dmax * LITE_BN_BYTES)
#define bn_words(b) ((b)->dmax)
#define bn_bits(b) ((b)->dmax * LITE_BN_BITS2)
int bn_eq(const struct LITE_BIGNUM *a, const struct LITE_BIGNUM *b);
int bn_check_topbit(const struct LITE_BIGNUM *N);
int bn_modexp(struct LITE_BIGNUM *output,
const struct LITE_BIGNUM *input,
const struct LITE_BIGNUM *exp,
const struct LITE_BIGNUM *N);
int bn_modexp_word(struct LITE_BIGNUM *output,
const struct LITE_BIGNUM *input,
uint32_t pubexp,
const struct LITE_BIGNUM *N);
int bn_modexp_blinded(struct LITE_BIGNUM *output,
const struct LITE_BIGNUM *input,
const struct LITE_BIGNUM *exp,
const struct LITE_BIGNUM *N,
uint32_t pubexp);
uint32_t bn_add(struct LITE_BIGNUM *c,
const struct LITE_BIGNUM *a);
uint32_t bn_sub(struct LITE_BIGNUM *c,
const struct LITE_BIGNUM *a);
int bn_modinv_vartime(struct LITE_BIGNUM *r,
const struct LITE_BIGNUM *e,
const struct LITE_BIGNUM *MOD);
int bn_is_bit_set(const struct LITE_BIGNUM *a, int n);
/*
* Accelerated bn.
*/
int dcrypto_modexp(struct LITE_BIGNUM *output,
const struct LITE_BIGNUM *input,
const struct LITE_BIGNUM *exp,
const struct LITE_BIGNUM *N);
int dcrypto_modexp_word(struct LITE_BIGNUM *output,
const struct LITE_BIGNUM *input,
uint32_t pubexp,
const struct LITE_BIGNUM *N);
int dcrypto_modexp_blinded(struct LITE_BIGNUM *output,
const struct LITE_BIGNUM *input,
const struct LITE_BIGNUM *exp,
const struct LITE_BIGNUM *N,
uint32_t pubexp);
/*
* RFC6979 based DRBG for ECDSA signature.
*/
struct drbg_ctx {
uint32_t k[SHA256_DIGEST_WORDS];
uint32_t v[SHA256_DIGEST_WORDS];
};
void drbg_rfc6979_init(struct drbg_ctx *ctx, const p256_int *key,
const p256_int *message);
void drbg_rand_init(struct drbg_ctx *ctx);
void drbg_generate(struct drbg_ctx *ctx, p256_int *k_out);
void drbg_exit(struct drbg_ctx *ctx);
/*
* Accelerated p256.
*/
int dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg, const p256_int *key,
const p256_int *message, p256_int *r, p256_int *s)
__attribute__((warn_unused_result));
int dcrypto_p256_base_point_mul(const p256_int *k, p256_int *x, p256_int *y)
__attribute__((warn_unused_result));
int dcrypto_p256_point_mul(const p256_int *k,
const p256_int *in_x, const p256_int *in_y,
p256_int *x, p256_int *y)
__attribute__((warn_unused_result));
int dcrypto_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)
__attribute__((warn_unused_result));
int dcrypto_p256_is_valid_point(const p256_int *x, const p256_int *y)
__attribute__((warn_unused_result));
/*
* Accelerator runtime.
*
* Note dcrypto_init_and_lock grabs a mutex and dcrypto_unlock releases it.
* Do not use dcrypto_call, dcrypto_imem_load or dcrypto_dmem_load w/o holding
* the mutex.
*/
void dcrypto_init_and_lock(void);
void dcrypto_unlock(void);
uint32_t dcrypto_call(uint32_t adr) __attribute__((warn_unused_result));
void dcrypto_imem_load(size_t offset, const uint32_t *opcodes,
size_t n_opcodes);
void dcrypto_dmem_load(size_t offset, const void *words, size_t n_words);
/*
* Key ladder.
*/
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 /* ! __EC_CHIP_G_DCRYPTO_INTERNAL_H */