This ensures alignment and makes xor_block more efficient,
but it's mostly in preparation for later changes.

Signed-off-by: George Spelvin <li...@horizon.com>
---
 crypto/ansi_cprng.c | 73 ++++++++++++++++++++++++++++++-----------------------
 1 file changed, 41 insertions(+), 32 deletions(-)

diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c
index 9c8475a2..4d256d74 100644
--- a/crypto/ansi_cprng.c
+++ b/crypto/ansi_cprng.c
@@ -25,6 +25,15 @@
 
 #define DEFAULT_PRNG_KSZ 16
 #define DEFAULT_BLK_SZ 16
+#define BLK_INTS ((DEFAULT_BLK_SZ + 3) / 4)
+#define BLK_LONGS ((DEFAULT_BLK_SZ + 7) / 8)
+
+/* An aligned buffer thant can be accessed various ways */
+union cipherblock {
+       u8 b[DEFAULT_BLK_SZ];
+       u32 i[BLK_INTS];
+       u64 l[BLK_LONGS];
+};
 
 /*
  * Flags for the prng_context flags field
@@ -47,15 +56,15 @@ struct prng_context {
        spinlock_t prng_lock;
        u8 flags;
        u8 rand_read_pos;
-       u8 rand_data[DEFAULT_BLK_SZ];
-       u8 DT[DEFAULT_BLK_SZ];
-       u8 V[DEFAULT_BLK_SZ];
+       union cipherblock rand_data;
+       union cipherblock DT;
+       union cipherblock V;
        struct crypto_cipher *tfm;
 };
 
 static int dbg;
 
-static void hexdump(char const *note, const u8 buf[DEFAULT_BLK_SZ])
+static void hexdump(char const *note, const union cipherblock *buf)
 {
        if (dbg) {
                printk(KERN_CRIT "%s = %" __stringify(DEFAULT_BLK_SZ) "phN",
@@ -68,11 +77,11 @@ if (dbg)\
        printk(format, ##args);\
 } while (0)
 
-static void xor_block(const u8 in[DEFAULT_BLK_SZ], u8 out[DEFAULT_BLK_SZ])
+static void xor_block(const u64 in[BLK_LONGS], u64 out[BLK_LONGS])
 {
        int i;
 
-       for (i = 0; i < DEFAULT_BLK_SZ; i++)
+       for (i = 0; i < BLK_LONGS; i++)
                out[i] ^= in[i];
 }
 
@@ -83,20 +92,20 @@ static void xor_block(const u8 in[DEFAULT_BLK_SZ], u8 
out[DEFAULT_BLK_SZ])
 static int _get_more_prng_bytes(struct prng_context *ctx, bool cont_test)
 {
        int i;
-       u8 tmp[DEFAULT_BLK_SZ];
+       union cipherblock tmp;
 
        dbgprint(KERN_CRIT "Calling _get_more_prng_bytes for context %p\n",
                ctx);
 
-       hexdump("DT", ctx->DT);
-       hexdump("V", ctx->V);
+       hexdump("DT", &ctx->DT);
+       hexdump("V", &ctx->V);
 
        /*
         * Start by encrypting the counter value
         * This gives us an intermediate value I (stored in tmp)
         */
-       crypto_cipher_encrypt_one(ctx->tfm, tmp, ctx->DT);
-       hexdump("I", tmp);
+       crypto_cipher_encrypt_one(ctx->tfm, tmp.b, ctx->DT.b);
+       hexdump("I", &tmp);
 
        /*
         * Next xor I with our secret vector V.  Encrypt that result
@@ -104,16 +113,16 @@ static int _get_more_prng_bytes(struct prng_context *ctx, 
bool cont_test)
         * keep that output in ctx->V for the moment; we need the
         * previous rand_data for ons more thing.
         */
-       xor_block(tmp, ctx->V);
-       hexdump("V^I", ctx->V);
-       crypto_cipher_encrypt_one(ctx->tfm, ctx->V, ctx->V);
-       hexdump("R", ctx->V);
+       xor_block(tmp.l, ctx->V.l);
+       hexdump("V^I", &ctx->V);
+       crypto_cipher_encrypt_one(ctx->tfm, ctx->V.b, ctx->V.b);
+       hexdump("R", &ctx->V);
 
        /*
         * Check that we didn't produce the same random data that we
         * did last time around.
         */
-       if (!memcmp(ctx->V, ctx->rand_data, DEFAULT_BLK_SZ)) {
+       if (!memcmp(ctx->V.b, ctx->rand_data.b, DEFAULT_BLK_SZ)) {
                if (cont_test) {
                        panic("cprng %p Failed repetition check!\n", ctx);
                }
@@ -126,27 +135,27 @@ static int _get_more_prng_bytes(struct prng_context *ctx, 
bool cont_test)
        /*
         * Okay, the new data is okay, copy it to the buffer.
         */
-       memcpy(ctx->rand_data, ctx->V, DEFAULT_BLK_SZ);
+       ctx->rand_data = ctx->V;
 
        /*
         * Lastly xor the random data with I and encrypt that to obtain
         * a new secret vector V.
         */
-       xor_block(tmp, ctx->V);
-       hexdump("R^I", ctx->V);
-       memzero_explicit(tmp, DEFAULT_BLK_SZ);
-       crypto_cipher_encrypt_one(ctx->tfm, ctx->V, ctx->V);
-       hexdump("V'", ctx->V);
+       xor_block(tmp.l, ctx->V.l);
+       hexdump("R^I", &ctx->V);
+       memzero_explicit(tmp.b, DEFAULT_BLK_SZ);
+       crypto_cipher_encrypt_one(ctx->tfm, ctx->V.b, ctx->V.b);
+       hexdump("V'", &ctx->V);
 
        /*
         * Now update our DT value
         */
        for (i = DEFAULT_BLK_SZ - 1; i >= 0; i--) {
-               ctx->DT[i] += 1;
-               if (ctx->DT[i] != 0)
+               ctx->DT.b[i] += 1;
+               if (ctx->DT.b[i] != 0)
                        break;
        }
-       hexdump("DT'", ctx->DT);
+       hexdump("DT'", &ctx->DT);
 
        dbgprint("Returning new block for context %p\n", ctx);
 
@@ -175,7 +184,7 @@ static int get_prng_bytes(u8 *buf, unsigned int nbytes,
                /* Leading partial block */
                unsigned int avail = DEFAULT_BLK_SZ - read_pos;
 
-               memcpy(ptr, ctx->rand_data + read_pos, avail);
+               memcpy(ptr, ctx->rand_data.b + read_pos, avail);
                ptr += avail;
                byte_count -= avail;
                read_pos = 0;
@@ -188,14 +197,14 @@ static int get_prng_bytes(u8 *buf, unsigned int nbytes,
                        }
                        if (byte_count < DEFAULT_BLK_SZ)
                                break;
-                       memcpy(ptr, ctx->rand_data, DEFAULT_BLK_SZ);
+                       memcpy(ptr, ctx->rand_data.b, DEFAULT_BLK_SZ);
                        ptr += DEFAULT_BLK_SZ;
                        byte_count -= DEFAULT_BLK_SZ;
                }
        }
 
        /* The final partial block; read_pos + byte_count <= DEFAULT_BLK_SZ */
-       memcpy(ptr, ctx->rand_data + read_pos, byte_count);
+       memcpy(ptr, ctx->rand_data.b + read_pos, byte_count);
        ctx->rand_read_pos = read_pos + byte_count;
        err = nbytes;
 
@@ -220,13 +229,13 @@ static int reset_prng_context(struct prng_context *ctx, 
const u8 *key,
        ctx->flags |= PRNG_NEED_RESET;
        ctx->rand_read_pos = DEFAULT_BLK_SZ;
 
-       memset(ctx->rand_data, 0, DEFAULT_BLK_SZ);
+       memset(ctx->rand_data.b, 0, DEFAULT_BLK_SZ);
 
        if (!DT)
-               DT = ctx->rand_data;    /* Use all-zeros if NULL */
+               DT = ctx->rand_data.b;  /* Use all-zeros if NULL */
 
-       memcpy(ctx->DT, DT, DEFAULT_BLK_SZ);
-       memcpy(ctx->V, V, DEFAULT_BLK_SZ);
+       memcpy(ctx->DT.b, DT, DEFAULT_BLK_SZ);
+       memcpy(ctx->V.b, V, DEFAULT_BLK_SZ);
 
        ret = crypto_cipher_setkey(ctx->tfm, key, klen);
        if (ret) {
-- 
2.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to