]> git.codecow.com Git - Monocypher.git/commitdiff
Avoid negating unsigned numbers (for MSVC)
authorLoup Vaillant <loup@loup-vaillant.fr>
Tue, 3 Apr 2018 19:54:49 +0000 (21:54 +0200)
committerLoup Vaillant <loup@loup-vaillant.fr>
Tue, 3 Apr 2018 19:54:49 +0000 (21:54 +0200)
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.

src/monocypher.c
src/optional/sha512.c

index d0f1651e6c29a166c8d22518d21512a577b934a8..4f9c85c546046aa483d7ab6f7ead4a5bd8a78860 100644 (file)
 #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);
index ae64595e4435eec2f61bdb691a8ee097fddffe88..5833d192ae27d631b355e8821501d1d78a928c99 100644 (file)
@@ -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;