From: Loup Vaillant Date: Tue, 3 Apr 2018 19:54:49 +0000 (+0200) Subject: Avoid negating unsigned numbers (for MSVC) X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=c63252ada2e190110cb2353c3c1db72c264d7647;p=Monocypher.git Avoid negating unsigned numbers (for MSVC) MSVC doesn't like when people negate unsigned numbers, and the result is still unsigned. By default, it's an error. Moreover, section 6.5.6 of the C11 standard doesn't clearly specify what -x means when x is an unsigned integer. It does however specify ~x. So I replaced -x by ~x+1. This was getting ugly, though, so I made the ALIGN macro. ALIGN(x, block_size) returns how many bytes we need to reach the next block size, assuming we've already consumed x bytes. For instance, ALIGN(11, 8) == 5. It uses bit twiddling trickery, so the block size must be a power of 2. --- diff --git a/src/monocypher.c b/src/monocypher.c index d0f1651..4f9c85c 100644 --- a/src/monocypher.c +++ b/src/monocypher.c @@ -20,17 +20,17 @@ #define HASH_UPDATE COMBINE2(HASH, _update) #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)) +#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)) +#define MIN(a, b) ((a) <= (b) ? (a) : (b)) +#define ALIGN(x, block_size) ((~(x) + 1) & ((block_size) - 1)) typedef uint8_t u8; typedef uint32_t u32; typedef int32_t i32; typedef int64_t i64; typedef uint64_t u64; -#define MIN(a, b) ((a) <= (b) ? (a) : (b)) - static u32 load24_le(const u8 s[3]) { return (u32)s[0] @@ -237,7 +237,7 @@ void crypto_chacha20_encrypt(crypto_chacha_ctx *ctx, size_t text_size) { // Align ourselves with block boundaries - size_t align = MIN(-ctx->pool_idx & 63, text_size); + size_t align = MIN(ALIGN(ctx->pool_idx, 64), text_size); chacha20_encrypt(ctx, cipher_text, plain_text, align); if (plain_text != 0) { plain_text += align; @@ -378,7 +378,7 @@ void crypto_poly1305_update(crypto_poly1305_ctx *ctx, const u8 *message, size_t message_size) { // Align ourselves with block boundaries - size_t align = MIN(-ctx->c_idx & 15, message_size); + size_t align = MIN(ALIGN(ctx->c_idx, 16), message_size); poly_update(ctx, message, align); message += align; message_size -= align; @@ -584,7 +584,7 @@ void crypto_blake2b_update(crypto_blake2b_ctx *ctx, const u8 *message, size_t message_size) { // Align ourselves with block boundaries - size_t align = MIN(-ctx->input_idx & 127, message_size); + size_t align = MIN(ALIGN(ctx->input_idx, 128), message_size); blake2b_update(ctx, message, align); message += align; message_size -= align; @@ -1712,7 +1712,7 @@ static void lock_ad_padding(crypto_lock_ctx *ctx) static const u8 zero[15] = {0}; if (ctx->ad_phase) { ctx->ad_phase = 0; - crypto_poly1305_update(&ctx->poly, zero, -ctx->ad_size & 15); + crypto_poly1305_update(&ctx->poly, zero, ALIGN(ctx->ad_size, 16)); } } @@ -1756,7 +1756,7 @@ void crypto_lock_final(crypto_lock_ctx *ctx, u8 mac[16]) u8 sizes[16]; store64_le(sizes + 0, ctx->ad_size); store64_le(sizes + 8, ctx->message_size); - crypto_poly1305_update(&ctx->poly, zero, -ctx->message_size & 15); + crypto_poly1305_update(&ctx->poly, zero, ALIGN(ctx->message_size, 16)); crypto_poly1305_update(&ctx->poly, sizes, 16); crypto_poly1305_final (&ctx->poly, mac); WIPE_CTX(ctx); diff --git a/src/optional/sha512.c b/src/optional/sha512.c index ae64595..5833d19 100644 --- a/src/optional/sha512.c +++ b/src/optional/sha512.c @@ -1,8 +1,9 @@ #include "sha512.h" -#define FOR(i, min, max) for (size_t i = min; i < max; i++) -#define WIPE_CTX(ctx) crypto_wipe(ctx , sizeof(*(ctx))) -#define MIN(a, b) ((a) <= (b) ? (a) : (b)) +#define FOR(i, min, max) for (size_t i = min; i < max; i++) +#define WIPE_CTX(ctx) crypto_wipe(ctx , sizeof(*(ctx))) +#define MIN(a, b) ((a) <= (b) ? (a) : (b)) +#define ALIGN(x, block_size) ((~(x) + 1) & ((block_size) - 1)) typedef uint8_t u8; typedef uint64_t u64; @@ -154,7 +155,7 @@ void crypto_sha512_update(crypto_sha512_ctx *ctx, const u8 *message, size_t message_size) { // Align ourselves with block boundaries - size_t align = MIN(-ctx->input_idx & 127, message_size); + size_t align = MIN(ALIGN(ctx->input_idx, 128), message_size); sha512_update(ctx, message, align); message += align; message_size -= align;