Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[pandora-kernel.git] / arch / s390 / crypto / sha256_s390.c
index b75bdbd..f573df3 100644 (file)
@@ -31,9 +31,9 @@ struct s390_sha256_ctx {
        u8 buf[2 * SHA256_BLOCK_SIZE];
 };
 
-static void sha256_init(void *ctx)
+static void sha256_init(struct crypto_tfm *tfm)
 {
-       struct s390_sha256_ctx *sctx = ctx;
+       struct s390_sha256_ctx *sctx = crypto_tfm_ctx(tfm);
 
        sctx->state[0] = 0x6a09e667;
        sctx->state[1] = 0xbb67ae85;
@@ -44,13 +44,14 @@ static void sha256_init(void *ctx)
        sctx->state[6] = 0x1f83d9ab;
        sctx->state[7] = 0x5be0cd19;
        sctx->count = 0;
-       memset(sctx->buf, 0, sizeof(sctx->buf));
 }
 
-static void sha256_update(void *ctx, const u8 *data, unsigned int len)
+static void sha256_update(struct crypto_tfm *tfm, const u8 *data,
+                         unsigned int len)
 {
-       struct s390_sha256_ctx *sctx = ctx;
+       struct s390_sha256_ctx *sctx = crypto_tfm_ctx(tfm);
        unsigned int index;
+       int ret;
 
        /* how much is already in the buffer? */
        index = sctx->count / 8 & 0x3f;
@@ -58,15 +59,29 @@ static void sha256_update(void *ctx, const u8 *data, unsigned int len)
        /* update message bit length */
        sctx->count += len * 8;
 
-       /* process one block */
-       if ((index + len) >= SHA256_BLOCK_SIZE) {
+       if ((index + len) < SHA256_BLOCK_SIZE)
+               goto store;
+
+       /* process one stored block */
+       if (index) {
                memcpy(sctx->buf + index, data, SHA256_BLOCK_SIZE - index);
-               crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf,
-                               SHA256_BLOCK_SIZE);
+               ret = crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf,
+                                     SHA256_BLOCK_SIZE);
+               BUG_ON(ret != SHA256_BLOCK_SIZE);
                data += SHA256_BLOCK_SIZE - index;
                len -= SHA256_BLOCK_SIZE - index;
        }
 
+       /* process as many blocks as possible */
+       if (len >= SHA256_BLOCK_SIZE) {
+               ret = crypt_s390_kimd(KIMD_SHA_256, sctx->state, data,
+                                     len & ~(SHA256_BLOCK_SIZE - 1));
+               BUG_ON(ret != (len & ~(SHA256_BLOCK_SIZE - 1)));
+               data += ret;
+               len -= ret;
+       }
+
+store:
        /* anything left? */
        if (len)
                memcpy(sctx->buf + index , data, len);
@@ -93,9 +108,9 @@ static void pad_message(struct s390_sha256_ctx* sctx)
 }
 
 /* Add padding and return the message digest */
-static void sha256_final(void* ctx, u8 *out)
+static void sha256_final(struct crypto_tfm *tfm, u8 *out)
 {
-       struct s390_sha256_ctx *sctx = ctx;
+       struct s390_sha256_ctx *sctx = crypto_tfm_ctx(tfm);
 
        /* must perform manual padding */
        pad_message(sctx);
@@ -119,9 +134,9 @@ static struct crypto_alg alg = {
        .cra_list       =       LIST_HEAD_INIT(alg.cra_list),
        .cra_u          =       { .digest = {
        .dia_digestsize =       SHA256_DIGEST_SIZE,
-       .dia_init       =       sha256_init,
-       .dia_update     =       sha256_update,
-       .dia_final      =       sha256_final } }
+       .dia_init       =       sha256_init,
+       .dia_update     =       sha256_update,
+       .dia_final      =       sha256_final } }
 };
 
 static int init(void)