summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Sukhomlinov <sukhomlinov@google.com>2019-08-23 17:39:13 -0700
committerCommit Bot <commit-bot@chromium.org>2019-08-29 04:55:21 +0000
commit4646e28429402438a294b93685bcea1d97f02b4d (patch)
tree08d8c457f7773869d1f1e3ad771363844fc1673b
parentfa0f71d9d92981cfcee72da870693d95f2b8d73b (diff)
downloadchrome-ec-4646e28429402438a294b93685bcea1d97f02b4d.tar.gz
cr50: added references to FIPS / NIST standards to cryptographic functions
Clarified standards compliance status for cryptographic functions. BRANCH=cr50 BUG=b:138574542 TEST=code compiles, unit tests pass Change-Id: I75ce155b53d1ce049e5063d2aaa1464b75f7d678 Signed-off-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1769420 Reviewed-by: Andrey Pronin <apronin@chromium.org>
-rw-r--r--chip/g/dcrypto/aes_cmac.c2
-rw-r--r--chip/g/dcrypto/dcrypto.h125
-rw-r--r--chip/g/dcrypto/hmac_drbg.c2
-rw-r--r--chip/g/dcrypto/internal.h2
4 files changed, 109 insertions, 22 deletions
diff --git a/chip/g/dcrypto/aes_cmac.c b/chip/g/dcrypto/aes_cmac.c
index 916c84611d..4f996f42b6 100644
--- a/chip/g/dcrypto/aes_cmac.c
+++ b/chip/g/dcrypto/aes_cmac.c
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* AES-CMAC-128 implementation according to RFC4493 */
+/* AES-CMAC-128 implementation according to NIST SP 800-38B, RFC4493 */
#include "console.h"
#include "dcrypto.h"
diff --git a/chip/g/dcrypto/dcrypto.h b/chip/g/dcrypto/dcrypto.h
index 7a186e790e..7bab4b864b 100644
--- a/chip/g/dcrypto/dcrypto.h
+++ b/chip/g/dcrypto/dcrypto.h
@@ -24,10 +24,10 @@ extern "C" {
#include "cryptoc/hmac.h"
enum cipher_mode {
- CIPHER_MODE_ECB = 0,
- CIPHER_MODE_CTR = 1,
- CIPHER_MODE_CBC = 2,
- CIPHER_MODE_GCM = 3
+ CIPHER_MODE_ECB = 0, /* NIST SP 800-38A */
+ CIPHER_MODE_CTR = 1, /* NIST SP 800-38A */
+ CIPHER_MODE_CBC = 2, /* NIST SP 800-38A */
+ CIPHER_MODE_GCM = 3 /* NIST SP 800-38D */
};
enum encrypt_mode {
@@ -45,6 +45,7 @@ enum hashing_mode {
/*
* AES implementation, based on a hardware AES block.
+ * FIPS Publication 197, The Advanced Encryption Standard (AES)
*/
#define AES256_BLOCK_CIPHER_KEY_SIZE 32
@@ -54,10 +55,19 @@ int DCRYPTO_aes_block(const uint8_t *in, uint8_t *out);
void DCRYPTO_aes_write_iv(const uint8_t *iv);
void DCRYPTO_aes_read_iv(uint8_t *iv);
+
+/* AES-CTR-128/192/256
+ * NIST Special Publication 800-38A
+ */
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);
-/* AES-GCM-128 */
+/* AES-GCM-128/192/256
+ * NIST Special Publication 800-38D, IV is provided externally
+ * Caller should use IV length according to section 8.2 of SP 800-38D
+ * And choose appropriate IV construction method, constrain number
+ * of invocations according to section 8.3 of SP 800-38D
+ */
struct GCM_CTX {
union {
uint32_t d[4];
@@ -99,8 +109,9 @@ int DCRYPTO_gcm_tag(struct GCM_CTX *ctx, uint8_t *tag, size_t tag_len);
/* Cleanup secrets. */
void DCRYPTO_gcm_finish(struct GCM_CTX *ctx);
-/* AES-CMAC-128 */
-/* K: 128-bit key, M: message, len: number of bytes in M
+/* AES-CMAC-128
+ * NIST Special Publication 800-38B, RFC 4493
+ * K: 128-bit key, M: message, len: number of bytes in M
* Writes 128-bit tag to T; returns 0 if an error is encountered and 1
* otherwise.
*/
@@ -123,6 +134,8 @@ int DCRYPTO_aes_cmac_verify(const uint8_t *key, const uint8_t *M, const int len,
* this particular hashing session.
*/
void DCRYPTO_SHA1_init(SHA_CTX *ctx, uint32_t sw_required);
+/* SHA256/384/512 FIPS 180-4
+ */
void DCRYPTO_SHA256_init(LITE_SHA256_CTX *ctx, uint32_t sw_required);
void DCRYPTO_SHA384_init(LITE_SHA384_CTX *ctx);
void DCRYPTO_SHA512_init(LITE_SHA512_CTX *ctx);
@@ -135,7 +148,7 @@ const uint8_t *DCRYPTO_SHA384_hash(const void *data, uint32_t n,
const uint8_t *DCRYPTO_SHA512_hash(const void *data, uint32_t n,
uint8_t *digest);
/*
- * HMAC.
+ * HMAC. FIPS 198-1
*/
void DCRYPTO_HMAC_SHA256_init(LITE_HMAC_CTX *ctx, const void *key,
unsigned int len);
@@ -181,24 +194,32 @@ enum padding_mode {
PADDING_MODE_NULL = 3
};
-/* Calculate r = m ^ e mod N */
+/* RSA support, FIPS PUB 186-4 *
+ * Calculate r = m ^ e mod N
+ */
int DCRYPTO_rsa_encrypt(struct RSA *rsa, uint8_t *out, uint32_t *out_len,
const uint8_t *in, uint32_t in_len,
enum padding_mode padding, enum hashing_mode hashing,
const char *label);
-/* Calculate r = m ^ d mod N */
+/* Calculate r = m ^ d mod N
+ * return 0 if error
+ */
int DCRYPTO_rsa_decrypt(struct RSA *rsa, uint8_t *out, uint32_t *out_len,
const uint8_t *in, const uint32_t in_len,
enum padding_mode padding, enum hashing_mode hashing,
const char *label);
-/* Calculate r = m ^ d mod N */
+/* Calculate r = m ^ d mod N
+ * return 0 if error
+ */
int DCRYPTO_rsa_sign(struct RSA *rsa, uint8_t *out, uint32_t *out_len,
const uint8_t *in, const uint32_t in_len,
enum padding_mode padding, enum hashing_mode hashing);
-/* Calculate r = m ^ e mod N */
+/* Calculate r = m ^ e mod N
+ * return 0 if error
+ */
int DCRYPTO_rsa_verify(const struct RSA *rsa, const uint8_t *digest,
uint32_t digest_len, const uint8_t *sig,
const uint32_t sig_len, enum padding_mode padding,
@@ -212,22 +233,39 @@ int DCRYPTO_rsa_key_compute(struct LITE_BIGNUM *N, struct LITE_BIGNUM *d,
/*
* EC.
*/
+
+/* DCRYPTO_p256_base_point_mul sets {out_x,out_y} = nG, where n is < the
+ * order of the group.
+ */
int DCRYPTO_p256_base_point_mul(p256_int *out_x, p256_int *out_y,
const p256_int *n);
+
+/* DCRYPTO_p256_point_mul sets {out_x,out_y} = n*{in_x,in_y}, where n is <
+ * the order of the group.
+ */
int DCRYPTO_p256_point_mul(p256_int *out_x, p256_int *out_y,
const p256_int *n, const p256_int *in_x,
const p256_int *in_y);
/*
+ * Key selection based on FIPS-186-4, section B.4.2 (Key Pair
+ * Generation by Testing Candidates).
* Produce uniform private key from seed.
* If x or y is NULL, the public key part is not computed.
* Returns !0 on success.
*/
int DCRYPTO_p256_key_from_bytes(p256_int *x, p256_int *y, p256_int *d,
const uint8_t bytes[P256_NBYTES]);
-/* 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. */
-/* Supports in-place encryption / decryption. */
+
+
+/* P256 based integration encryption (DH+AES128+SHA256).
+ * Not FIPS 140-2 compliant, not used other than for tests
+ * Authenticated data may be provided, where the first auth_data_len
+ * bytes of in will be authenticated but not encrypted. *
+ * Supports in-place encryption / decryption. *
+ * The output format is:
+ * 0x04 || PUBKEY || AUTH_DATA || AES128_CTR(PLAINTEXT) ||
+ * HMAC_SHA256(AUTH_DATA || CIPHERTEXT)
+ */
size_t DCRYPTO_ecies_encrypt(
void *out, size_t out_len, const void *in, size_t in_len,
size_t auth_data_len, const uint8_t *iv,
@@ -242,7 +280,10 @@ size_t DCRYPTO_ecies_decrypt(
const uint8_t *info, size_t info_len);
/*
- * HKDF.
+ * HKDF as per RFC 5869. Mentioned as conforming NIST SP 800-56C Rev.1
+ * [RFC 5869] specifies a version of the above extraction-then-expansion
+ * key-derivation procedure using HMAC for both the extraction and expansion
+ * steps.
*/
int DCRYPTO_hkdf(uint8_t *OKM, size_t OKM_len,
const uint8_t *salt, size_t salt_len,
@@ -252,6 +293,10 @@ int DCRYPTO_hkdf(uint8_t *OKM, size_t OKM_len,
/*
* BN.
*/
+
+/* Apply Miller-Rabin test for prime candidate p.
+ * Returns 1 if test passed, 0 otherwise
+ */
int DCRYPTO_bn_generate_prime(struct LITE_BIGNUM *p);
void DCRYPTO_bn_wrap(struct LITE_BIGNUM *b, void *buf, size_t len);
void DCRYPTO_bn_mul(struct LITE_BIGNUM *c, const struct LITE_BIGNUM *a,
@@ -269,16 +314,56 @@ size_t DCRYPTO_asn1_pubp(uint8_t *buf, const p256_int *x, const p256_int *y);
/*
* X509.
*/
+/* DCRYPTO_x509_verify verifies that the provided X509 certificate was issued
+ * by the specified certifcate authority.
+ *
+ * cert is a pointer to a DER encoded X509 certificate, as specified
+ * in https://tools.ietf.org/html/rfc5280#section-4.1. In ASN.1
+ * notation, the certificate has the following structure:
+ *
+ * Certificate ::= SEQUENCE {
+ * tbsCertificate TBSCertificate,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signatureValue BIT STRING }
+ *
+ * TBSCertificate ::= SEQUENCE { }
+ * AlgorithmIdentifier ::= SEQUENCE { }
+ *
+ * where signatureValue = SIGN(HASH(tbsCertificate)), with SIGN and
+ * HASH specified by signatureAlgorithm.
+ * Accepts only certs with OID: sha256WithRSAEncryption:
+ * 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00
+ */
int DCRYPTO_x509_verify(const uint8_t *cert, size_t len,
const struct RSA *ca_pub_key);
-int DCRYPTO_x509_gen_u2f_cert(const p256_int *d, const p256_int *pk_x,
- const p256_int *pk_y, const p256_int *serial,
- uint8_t *cert, const int n);
+
+/* Generate U2F Certificate and sign it
+ * Use ECDSA with NIST P-256 curve, and SHA2-256 digest
+ * @param d: key handle, used for NIST SP 800-90A HMAC DRBG
+ * @param pk_x, pk_y: public key
+ * @param serial: serial number for certificate
+ * @param name: certificate issuer and subject
+ * @param cert: output buffer for certificate
+ * @param n: max size of cert
+ */
int DCRYPTO_x509_gen_u2f_cert_name(const p256_int *d, const p256_int *pk_x,
const p256_int *pk_y, const p256_int *serial,
const char *name, uint8_t *cert,
const int n);
+/* Generate U2F Certificate with DCRYPTO_x509_gen_u2f_cert_name
+ * Providing certificate issuer as BOARD or U2F
+ * @param d: key handle, used for NIST SP 800-90A HMAC DRBG
+ * @param pk_x, pk_y: public key
+ * @param serial: serial number for certificate
+ * @param name: certificate issuer and subject
+ * @param cert: output buffer for certificate
+ * @param n: max size of cert
+ */
+int DCRYPTO_x509_gen_u2f_cert(const p256_int *d, const p256_int *pk_x,
+ const p256_int *pk_y, const p256_int *serial,
+ uint8_t *cert, const int n);
+
/*
* Memory related functions.
*/
diff --git a/chip/g/dcrypto/hmac_drbg.c b/chip/g/dcrypto/hmac_drbg.c
index 5ddf9bf282..64b47a13f5 100644
--- a/chip/g/dcrypto/hmac_drbg.c
+++ b/chip/g/dcrypto/hmac_drbg.c
@@ -9,6 +9,8 @@
#include "internal.h"
#include "trng.h"
+/* HMAC_DRBG flow in NIST SP 800-90Ar1, 10.2, RFC 6979
+ */
/* V = HMAC(K, V) */
static void update_v(const uint32_t *k, uint32_t *v)
{
diff --git a/chip/g/dcrypto/internal.h b/chip/g/dcrypto/internal.h
index 84c0e8fde9..69c54da4d4 100644
--- a/chip/g/dcrypto/internal.h
+++ b/chip/g/dcrypto/internal.h
@@ -154,7 +154,7 @@ void hmac_drbg_generate_p256(struct drbg_ctx *ctx, p256_int *k_out);
void drbg_exit(struct drbg_ctx *ctx);
/*
- * Accelerated p256.
+ * Accelerated p256. FIPS PUB 186-4
*/
int dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg, const p256_int *key,
const p256_int *message, p256_int *r, p256_int *s)