aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMattias Nissler <mnissler@google.com>2016-03-22 14:47:30 +0100
committerKenny Root <kroot@google.com>2019-06-13 12:44:55 +0000
commit4b143c1a4329732b7d7b21be35d972c7bfd216b1 (patch)
tree32d72328c06543fd8638fe6fd422e6c7c3ed7242
parent3f7c2ead52dbdc19b5077032831496e386ce977e (diff)
downloadlibconstrainedcrypto-main.tar.gz
Sync code with Google-internal version.HEADandroid-o-mr1-iot-release-1.0.14mastermain
This brings the constrainedcrypto code back in sync with the respective Google-internal copy of this code. Changes are mostly cosmetic (some explicit casts, some int -> unsigned int changes), the only major change is additional p256 code. We don't use the p256 code right now, but I'm adding it in an effort to keep the files from diverging too much. BUG: 27287913 Change-Id: Ie8672bbb2487d576ab4c5f6dda4ab6c194575985
-rw-r--r--include/constrainedcrypto/hash-internal.h6
-rw-r--r--include/constrainedcrypto/sha.h4
-rw-r--r--include/constrainedcrypto/sha256.h4
-rw-r--r--p256.c78
-rw-r--r--p256_ec.c17
-rw-r--r--p256_ecdsa.c1
-rw-r--r--sha.c14
-rw-r--r--sha256.c13
8 files changed, 115 insertions, 22 deletions
diff --git a/include/constrainedcrypto/hash-internal.h b/include/constrainedcrypto/hash-internal.h
index f0a00f9..add1c90 100644
--- a/include/constrainedcrypto/hash-internal.h
+++ b/include/constrainedcrypto/hash-internal.h
@@ -37,10 +37,10 @@ struct HASH_CTX; // forward decl
typedef struct HASH_VTAB {
void (* const init)(struct HASH_CTX*);
- void (* const update)(struct HASH_CTX*, const void*, int);
+ void (* const update)(struct HASH_CTX*, const void*, unsigned int);
const uint8_t* (* const final)(struct HASH_CTX*);
- const uint8_t* (* const hash)(const void*, int, uint8_t*);
- int size;
+ const uint8_t* (* const hash)(const void*, unsigned int, uint8_t*);
+ unsigned int size;
} HASH_VTAB;
typedef struct HASH_CTX {
diff --git a/include/constrainedcrypto/sha.h b/include/constrainedcrypto/sha.h
index 94dcdb4..e07b125 100644
--- a/include/constrainedcrypto/sha.h
+++ b/include/constrainedcrypto/sha.h
@@ -36,12 +36,12 @@ extern "C" {
typedef HASH_CTX SHA_CTX;
void SHA_init(SHA_CTX* ctx);
-void SHA_update(SHA_CTX* ctx, const void* data, int len);
+void SHA_update(SHA_CTX* ctx, const void* data, unsigned int len);
const uint8_t* SHA_final(SHA_CTX* ctx);
// Convenience method. Returns digest address.
// NOTE: *digest needs to hold SHA_DIGEST_SIZE bytes.
-const uint8_t* SHA_hash(const void* data, int len, uint8_t* digest);
+const uint8_t* SHA_hash(const void* data, unsigned int len, uint8_t* digest);
#define SHA_DIGEST_SIZE 20
diff --git a/include/constrainedcrypto/sha256.h b/include/constrainedcrypto/sha256.h
index eb2917c..5feab38 100644
--- a/include/constrainedcrypto/sha256.h
+++ b/include/constrainedcrypto/sha256.h
@@ -37,11 +37,11 @@ extern "C" {
typedef HASH_CTX SHA256_CTX;
void SHA256_init(SHA256_CTX* ctx);
-void SHA256_update(SHA256_CTX* ctx, const void* data, int len);
+void SHA256_update(SHA256_CTX* ctx, const void* data, unsigned int len);
const uint8_t* SHA256_final(SHA256_CTX* ctx);
// Convenience method. Returns digest address.
-const uint8_t* SHA256_hash(const void* data, int len, uint8_t* digest);
+const uint8_t* SHA256_hash(const void* data, unsigned int len, uint8_t* digest);
#define SHA256_DIGEST_SIZE 32
diff --git a/p256.c b/p256.c
index 993cd4e..ddf0bac 100644
--- a/p256.c
+++ b/p256.c
@@ -42,6 +42,9 @@
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 }};
@@ -49,6 +52,9 @@ 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));
}
@@ -188,6 +194,7 @@ void p256_modmul(const p256_int* MOD,
memcpy(c, tmp, P256_NBYTES);
}
+
int p256_is_odd(const p256_int* a) { return P256_DIGIT(a, 0) & 1; }
int p256_is_even(const p256_int* a) { return !(P256_DIGIT(a, 0) & 1); }
@@ -287,6 +294,61 @@ int p256_add_d(const p256_int* a, p256_digit d, p256_int* b) {
return (int)carry;
}
+// if (mask) dst = src, fixed-timing style.
+static void copyConditional(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) {
+ copyConditional(&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) {
+ p256_int tbl[16];
+ int i;
+
+ // 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]);
+ copyConditional(&tbl[0], b, ~ZEROtoONES(idx));
+ }
+}
+
// b = 1/a mod MOD, binary euclid.
void p256_modinv_vartime(const p256_int* MOD,
const p256_int* a,
@@ -354,6 +416,8 @@ int p256_is_valid_point(const p256_int* x, const p256_int* y) {
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;
}
@@ -371,3 +435,17 @@ void p256_from_bin(const uint8_t src[P256_NBYTES], p256_int* dst) {
p += 4;
}
}
+
+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 digit = P256_DIGIT(src, i);
+ p[0] = (uint8_t)(digit >> 24);
+ p[1] = (uint8_t)(digit >> 16);
+ p[2] = (uint8_t)(digit >> 8);
+ p[3] = (uint8_t)(digit);
+ p += 4;
+ }
+}
diff --git a/p256_ec.c b/p256_ec.c
index 72e80e6..4dc02d4 100644
--- a/p256_ec.c
+++ b/p256_ec.c
@@ -791,7 +791,6 @@ static char felem_is_zero_vartime(const felem in) {
memcmp(tmp, k2P, sizeof(tmp)) == 0;
}
-
/* Group operations:
*
* Elements of the elliptic curve group are represented in Jacobian
@@ -1236,6 +1235,22 @@ void p256_base_point_mul(const p256_int* n, p256_int* out_x, p256_int* out_y) {
}
}
+/* p256_point_mul sets {out_x,out_y} = n*{in_x,in_y}, where n is <
+ * the order of the group. */
+void p256_point_mul(const p256_int* n, const p256_int* in_x,
+ const p256_int* in_y, p256_int* out_x, p256_int* out_y) {
+ felem x, y, z, px, py;
+
+ to_montgomery(px, in_x);
+ to_montgomery(py, in_y);
+
+ scalar_mult(x, y, z, px, py, n);
+
+ point_to_affine(px, py, x, y, z);
+ from_montgomery(out_x, px);
+ from_montgomery(out_y, py);
+}
+
/* p256_points_mul_vartime sets {out_x,out_y} = n1*G + n2*{in_x,in_y}, where
* n1 and n2 are < the order of the group.
*
diff --git a/p256_ecdsa.c b/p256_ecdsa.c
index 47dcd7b..c104aac 100644
--- a/p256_ecdsa.c
+++ b/p256_ecdsa.c
@@ -53,4 +53,3 @@ int p256_ecdsa_verify(const p256_int* key_x, const p256_int* key_y,
p256_mod(&SECP256r1_n, &u, &u); // (x coord % p) % n
return p256_cmp(r, &u) == 0;
}
-
diff --git a/sha.c b/sha.c
index 43440a0..5b27152 100644
--- a/sha.c
+++ b/sha.c
@@ -104,8 +104,8 @@ void SHA_init(SHA_CTX* ctx) {
}
-void SHA_update(SHA_CTX* ctx, const void* data, int len) {
- int i = (int) (ctx->count & 63);
+void SHA_update(SHA_CTX* ctx, const void* data, unsigned int len) {
+ unsigned int i = (unsigned int)(ctx->count & 63);
const uint8_t* p = (const uint8_t*)data;
ctx->count += len;
@@ -136,17 +136,17 @@ const uint8_t* SHA_final(SHA_CTX* ctx) {
for (i = 0; i < 5; i++) {
uint32_t tmp = ctx->state[i];
- *p++ = tmp >> 24;
- *p++ = tmp >> 16;
- *p++ = tmp >> 8;
- *p++ = tmp >> 0;
+ *p++ = (uint8_t)(tmp >> 24);
+ *p++ = (uint8_t)(tmp >> 16);
+ *p++ = (uint8_t)(tmp >> 8);
+ *p++ = (uint8_t)(tmp >> 0);
}
return ctx->buf;
}
/* Convenience function */
-const uint8_t* SHA_hash(const void* data, int len, uint8_t* digest) {
+const uint8_t* SHA_hash(const void* data, unsigned int len, uint8_t* digest) {
SHA_CTX ctx;
SHA_init(&ctx);
SHA_update(&ctx, data, len);
diff --git a/sha256.c b/sha256.c
index 2b5f073..5e91c8d 100644
--- a/sha256.c
+++ b/sha256.c
@@ -133,7 +133,7 @@ void SHA256_init(SHA256_CTX* ctx) {
}
-void SHA256_update(SHA256_CTX* ctx, const void* data, int len) {
+void SHA256_update(SHA256_CTX* ctx, const void* data, unsigned int len) {
int i = (int) (ctx->count & 63);
const uint8_t* p = (const uint8_t*)data;
@@ -165,17 +165,18 @@ const uint8_t* SHA256_final(SHA256_CTX* ctx) {
for (i = 0; i < 8; i++) {
uint32_t tmp = ctx->state[i];
- *p++ = tmp >> 24;
- *p++ = tmp >> 16;
- *p++ = tmp >> 8;
- *p++ = tmp >> 0;
+ *p++ = (uint8_t)(tmp >> 24);
+ *p++ = (uint8_t)(tmp >> 16);
+ *p++ = (uint8_t)(tmp >> 8);
+ *p++ = (uint8_t)(tmp >> 0);
}
return ctx->buf;
}
/* Convenience function */
-const uint8_t* SHA256_hash(const void* data, int len, uint8_t* digest) {
+const uint8_t* SHA256_hash(const void* data, unsigned int len,
+ uint8_t* digest) {
SHA256_CTX ctx;
SHA256_init(&ctx);
SHA256_update(&ctx, data, len);