return crypto_verify32(p, zero);
}
+void crypto_wipe(void *secret, size_t size)
+{
+ volatile u8 *v_secret = (u8*)secret;
+ FOR (i, 0, size) {
+ v_secret[i] = 0;
+ }
+}
+
/////////////////
/// Chacha 20 ///
/////////////////
u += (i64)(ctx->h[1]) + ctx->pad[1]; store32_le(mac + 4, u); u >>= 32;
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));
}
void crypto_poly1305_auth(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));
}
void crypto_blake2b_general(u8 *hash , size_t hash_size,
extended_hash(hash_area, 1024, initial_hash, 72);
load_block(&tmp_block, hash_area);
copy_block(blocks + 1, &tmp_block);
+
+ crypto_wipe(initial_hash, 72);
+ crypto_wipe(hash_area , 1024);
}
// Actual number of blocks
u8 final_block[1024];
store_block(final_block, blocks + (nb_blocks - 1));
extended_hash(hash, hash_size, final_block, 1024);
+
+ crypto_wipe(final_block , 1024);
+ // Note: the work area is *not* wiped by default. It would erase
+ // the final hash if the user wanted to use it to store the final
+ // hash, for instance to conserve stack space.
}
////////////////////////////////////
signature[i] = half_sig[i];
}
modL(signature + 32, s); // second half of the signature = s
+
+ crypto_wipe(ctx, sizeof(*ctx));
}
void crypto_sign(u8 signature[64],
void crypto_lock_final(crypto_lock_ctx *ctx, u8 mac[16])
{
- crypto_poly1305_final (&(ctx->poly), mac);
+ crypto_poly1305_final(&(ctx->poly), mac);
}
void crypto_unlock_update(crypto_lock_ctx *ctx, u8 *plain_text,
crypto_lock_auth (&ctx, ad, ad_size);
crypto_lock_update (&ctx, cipher_text, plain_text, text_size);
crypto_lock_final (&ctx, mac);
+ crypto_wipe(&(ctx.chacha), sizeof(ctx.chacha));
}
int crypto_aead_unlock(u8 *plain_text,
return -1; // reject forgeries before wasting our time decrypting
}
crypto_lock_encrypt(&ctx, plain_text, cipher_text, text_size);
+ crypto_wipe(&(ctx.chacha), sizeof(ctx.chacha));
return 0;
}
int crypto_verify32(const uint8_t a[32], const uint8_t b[32]);
int crypto_verify64(const uint8_t a[64], const uint8_t b[64]);
+// Erase a buffer from existence.
+// It probably wasn't the only copy...
+void crypto_wipe(void *secret, size_t size);
+
////////////////
/// Chacha20 ///
////////////////
typedef crypto_blake2b_ctx crypto_hash_ctx;
#endif
+// EdDSA signatures context. Do not rely on its contents or its size,
+// they may change without notice.
typedef struct {
crypto_hash_ctx hash;
uint8_t buf[96];
int crypto_check_public_key(const uint8_t public_key[32]);
+// EdDSA check context. Do not rely on its contents or its size, they
+// may change without notice.
typedef struct {
crypto_hash_ctx hash;
uint8_t sig[64];
////////////////////////////////
/// Authenticated encryption ///
////////////////////////////////
+
+// Authenticated encryption context. Do not rely on its contents or
+// its size, they may change without notice.
typedef struct {
crypto_chacha_ctx chacha;
crypto_poly1305_ctx poly;