#define HASH_FINAL COMBINE2(HASH, _final)
#define FOR(i, start, end) for (size_t (i) = (start); (i) < (end); (i)++)
+#define WIPE_CTX(ctx) crypto_wipe(ctx , sizeof(*(ctx)))
+#define WIPE_BUFFER(buffer) crypto_wipe(buffer, sizeof(buffer))
typedef uint8_t u8;
typedef uint32_t u32;
typedef int32_t i32;
store32_le(out + i*4, buffer[i ]); // constant
store32_le(out + 16 + i*4, buffer[i + 12]); // counter and nonce
}
- crypto_wipe(&ctx , sizeof(ctx ));
- crypto_wipe(buffer, sizeof(buffer));
+ WIPE_CTX(&ctx);
+ WIPE_BUFFER(buffer);
}
void crypto_chacha20_init(crypto_chacha_ctx *ctx,
u += (i64)(ctx->h[2]) + ctx->pad[2]; store32_le(mac + 8, u); u >>= 32;
u += (i64)(ctx->h[3]) + ctx->pad[3]; store32_le(mac + 12, u);
- crypto_wipe(ctx, sizeof(*ctx));
+ WIPE_CTX(ctx);
}
void crypto_poly1305(u8 mac[16], const u8 *message,
FOR (i, nb_words * 8, ctx->hash_size) {
hash[i] = (ctx->hash[i / 8] >> (8 * (i % 8))) & 0xff;
}
- crypto_wipe(ctx, sizeof(*ctx));
+ WIPE_CTX(ctx);
}
void crypto_blake2b_general(u8 *hash , size_t hash_size,
u8 buf[4];
store32_le(buf, input);
crypto_blake2b_update(ctx, buf, 4);
- crypto_wipe(buf, 4);
+ WIPE_BUFFER(buf);
}
static void load_block(block *b, const u8 bytes[1024])
blake_update_32 (&ctx, digest_size);
crypto_blake2b_update (&ctx, input, input_size);
crypto_blake2b_final (&ctx, digest);
- crypto_wipe(&ctx, sizeof(ctx));
+ WIPE_CTX(&ctx);
if (digest_size > 64) {
// the conversion to u64 avoids integer overflow on
load_block(&tmp_block, hash_area);
copy_block(blocks + 1, &tmp_block);
- crypto_wipe(initial_hash, 72);
- crypto_wipe(hash_area , 1024);
+ WIPE_BUFFER(initial_hash);
+ WIPE_BUFFER(hash_area);
wipe_block(&tmp_block);
}
extended_hash(hash, hash_size, final_block, 1024);
// wipe final block and work area
- crypto_wipe(final_block, 1024);
+ WIPE_BUFFER(final_block);
volatile u64 *p = (u64*)work_area;
FOR (i, 0, 128 * nb_blocks) {
p[i] = 0;
fe_sq(t3, t2); FOR (i, 1, 100) fe_sq(t3, t3); fe_mul(t2 , t3, t2);
fe_sq(t2, t2); FOR (i, 1, 50) fe_sq(t2, t2); fe_mul(t1 , t2, t1);
fe_sq(t1, t1); FOR (i, 1, 5) fe_sq(t1, t1); fe_mul(out, t1, t0);
- crypto_wipe(t0, sizeof(t0));
- crypto_wipe(t0, sizeof(t1));
- crypto_wipe(t0, sizeof(t2));
- crypto_wipe(t0, sizeof(t3));
+ WIPE_BUFFER(t0);
+ WIPE_BUFFER(t1);
+ WIPE_BUFFER(t2);
+ WIPE_BUFFER(t3);
}
// This could be simplified, but it would be slower
fe_sq(t2, t1); FOR (i, 1, 100) fe_sq(t2, t2); fe_mul(t1, t2, t1);
fe_sq(t1, t1); FOR (i, 1, 50) fe_sq(t1, t1); fe_mul(t0, t1, t0);
fe_sq(t0, t0); FOR (i, 1, 2) fe_sq(t0, t0); fe_mul(out, t0, z);
- crypto_wipe(t0, sizeof(t0));
- crypto_wipe(t0, sizeof(t1));
- crypto_wipe(t0, sizeof(t2));
+ WIPE_BUFFER(t0);
+ WIPE_BUFFER(t1);
+ WIPE_BUFFER(t2);
}
static void fe_tobytes(u8 s[32], const fe h)
store32_le(s + 24, ((u32)t[7] >> 13) | ((u32)t[8] << 12));
store32_le(s + 28, ((u32)t[8] >> 20) | ((u32)t[9] << 6));
- crypto_wipe(t, sizeof(t));
+ WIPE_BUFFER(t);
}
// Parity check. Returns 0 if even, 1 if odd
u8 s[32];
fe_tobytes(s, f);
u8 isneg = s[0] & 1;
- crypto_wipe(s, sizeof(s));
+ WIPE_BUFFER(s);
return isneg;
}
u8 s[32];
fe_tobytes(s, f);
u8 isnonzero = zerocmp32(s);
- crypto_wipe(s, sizeof(s));
+ WIPE_BUFFER(s);
return isnonzero;
}
fe_cswap(x2, x3, swap);
fe_cswap(z2, z3, swap);
- crypto_wipe(t0, sizeof(t0));
- crypto_wipe(t1, sizeof(t1));
+ WIPE_BUFFER(t0);
+ WIPE_BUFFER(t1);
}
int crypto_x25519(u8 raw_shared_secret[32],
fe_mul(x2, x2, z2);
fe_tobytes(raw_shared_secret, x2);
- crypto_wipe(x1, sizeof(x1));
- crypto_wipe(x2, sizeof(x2));
- crypto_wipe(z2, sizeof(z2));
- crypto_wipe(x3, sizeof(x3));
- crypto_wipe(z3, sizeof(z3));
- crypto_wipe(e , sizeof(e ));
+ WIPE_BUFFER(x1);
+ WIPE_BUFFER(x2); WIPE_BUFFER(z2);
+ WIPE_BUFFER(x3); WIPE_BUFFER(z3);
+ WIPE_BUFFER(e );
// Returns -1 if the input is all zero
// (happens with some malicious public keys)
fe_mul(y, h->Y, recip);
fe_tobytes(s, y);
s[31] ^= fe_isnegative(x) << 7;
- crypto_wipe(x, sizeof(x));
- crypto_wipe(y, sizeof(y));
+
+ WIPE_BUFFER(x);
+ WIPE_BUFFER(y);
}
// Variable time! s must not be secret!
fe_mul(p->X, x1, t2); fe_mul(p->Y, y1, t1); fe_mul(p->Z, y1, t2);
fe_mul(p->T, x1, t1);
- crypto_wipe(x1, sizeof(x1));
- crypto_wipe(y1, sizeof(y1));
- crypto_wipe(z1, sizeof(z1));
- crypto_wipe(x2, sizeof(x2));
- crypto_wipe(z2, sizeof(z2));
- crypto_wipe(x3, sizeof(x3));
- crypto_wipe(z3, sizeof(z3));
- crypto_wipe(t1, sizeof(t1));
- crypto_wipe(t2, sizeof(t2));
- crypto_wipe(t3, sizeof(t3));
- crypto_wipe(t4, sizeof(t4));
+ WIPE_BUFFER(x1); WIPE_BUFFER(y1); WIPE_BUFFER(z1);
+ WIPE_BUFFER(x2); WIPE_BUFFER(z2);
+ WIPE_BUFFER(x3); WIPE_BUFFER(z3);
+ WIPE_BUFFER(t1); WIPE_BUFFER(t2); WIPE_BUFFER(t3); WIPE_BUFFER(t4);
}
static void ge_scalarmult_base(ge *p, const u8 scalar[32])
r[i] = 0;
}
modL(r, x);
- crypto_wipe(x, sizeof(x));
+ WIPE_BUFFER(x);
}
void crypto_sign_public_key(u8 public_key[32],
ge A;
ge_scalarmult_base(&A, a);
ge_tobytes(public_key, &A);
- crypto_wipe( a, sizeof(a));
- crypto_wipe(&A, sizeof(A));
+ WIPE_BUFFER(a);
+ WIPE_CTX(&A);
}
void crypto_sign_init_first_pass(crypto_sign_ctx *ctx,
}
modL(signature + 32, s); // second half of the signature = s
- crypto_wipe(ctx , sizeof(*ctx ));
- crypto_wipe(h_ram, sizeof(h_ram));
- crypto_wipe(s , sizeof(s ));
+ WIPE_CTX(ctx);
+ WIPE_BUFFER(h_ram);
+ WIPE_BUFFER(s);
}
void crypto_sign(u8 signature[64],
int status = crypto_x25519(raw_shared_secret,
your_secret_key, their_public_key);
crypto_chacha20_H(shared_key, raw_shared_secret, zero);
- crypto_wipe(raw_shared_secret, 32);
+ WIPE_BUFFER(raw_shared_secret);
return status;
}
crypto_chacha20_x_init(&(ctx->chacha), key, nonce);
crypto_chacha20_stream(&(ctx->chacha), auth_key, 32);
crypto_poly1305_init (&(ctx->poly ), auth_key);
- crypto_wipe(auth_key, 32);
+ WIPE_BUFFER(auth_key);
}
void crypto_lock_encrypt(crypto_lock_ctx *ctx, u8 *cipher_text,
void crypto_lock_final(crypto_lock_ctx *ctx, u8 mac[16])
{
crypto_poly1305_final(&(ctx->poly), mac);
- crypto_wipe(ctx, sizeof(ctx));
+ WIPE_CTX(ctx);
}
void crypto_unlock_update(crypto_lock_ctx *ctx, u8 *plain_text,
u8 real_mac[16];
crypto_lock_final(ctx, real_mac);
int mismatch = crypto_verify16(real_mac, mac);
- crypto_wipe(real_mac, sizeof(real_mac));
+ WIPE_BUFFER(real_mac);
return mismatch;
}
crypto_lock_auth(&ctx, cipher_text, text_size);
crypto_chacha_ctx chacha_ctx = ctx.chacha; // avoid the wiping...
if (crypto_unlock_final(&ctx, mac)) { // ...that occurs here
- crypto_wipe(&chacha_ctx, sizeof(chacha_ctx));
+ WIPE_CTX(&chacha_ctx);
return -1; // reject forgeries before wasting our time decrypting
}
crypto_chacha20_encrypt(&chacha_ctx, plain_text, cipher_text, text_size);
- crypto_wipe(&chacha_ctx, sizeof(chacha_ctx));
+ WIPE_CTX(&chacha_ctx);
return 0;
}