linux/crypto/sha1_generic.c
<<
>>
Prefs
   1/*
   2 * Cryptographic API.
   3 *
   4 * SHA1 Secure Hash Algorithm.
   5 *
   6 * Derived from cryptoapi implementation, adapted for in-place
   7 * scatterlist interface.
   8 *
   9 * Copyright (c) Alan Smithee.
  10 * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
  11 * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
  12 *
  13 * This program is free software; you can redistribute it and/or modify it
  14 * under the terms of the GNU General Public License as published by the Free
  15 * Software Foundation; either version 2 of the License, or (at your option)
  16 * any later version.
  17 *
  18 */
  19#include <linux/init.h>
  20#include <linux/module.h>
  21#include <linux/mm.h>
  22#include <linux/crypto.h>
  23#include <linux/cryptohash.h>
  24#include <linux/types.h>
  25#include <crypto/sha.h>
  26#include <asm/byteorder.h>
  27
  28struct sha1_ctx {
  29        u64 count;
  30        u32 state[5];
  31        u8 buffer[64];
  32};
  33
  34static void sha1_init(struct crypto_tfm *tfm)
  35{
  36        struct sha1_ctx *sctx = crypto_tfm_ctx(tfm);
  37        static const struct sha1_ctx initstate = {
  38          0,
  39          { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
  40          { 0, }
  41        };
  42
  43        *sctx = initstate;
  44}
  45
  46static void sha1_update(struct crypto_tfm *tfm, const u8 *data,
  47                        unsigned int len)
  48{
  49        struct sha1_ctx *sctx = crypto_tfm_ctx(tfm);
  50        unsigned int partial, done;
  51        const u8 *src;
  52
  53        partial = sctx->count & 0x3f;
  54        sctx->count += len;
  55        done = 0;
  56        src = data;
  57
  58        if ((partial + len) > 63) {
  59                u32 temp[SHA_WORKSPACE_WORDS];
  60
  61                if (partial) {
  62                        done = -partial;
  63                        memcpy(sctx->buffer + partial, data, done + 64);
  64                        src = sctx->buffer;
  65                }
  66
  67                do {
  68                        sha_transform(sctx->state, src, temp);
  69                        done += 64;
  70                        src = data + done;
  71                } while (done + 63 < len);
  72
  73                memset(temp, 0, sizeof(temp));
  74                partial = 0;
  75        }
  76        memcpy(sctx->buffer + partial, src, len - done);
  77}
  78
  79
  80/* Add padding and return the message digest. */
  81static void sha1_final(struct crypto_tfm *tfm, u8 *out)
  82{
  83        struct sha1_ctx *sctx = crypto_tfm_ctx(tfm);
  84        __be32 *dst = (__be32 *)out;
  85        u32 i, index, padlen;
  86        __be64 bits;
  87        static const u8 padding[64] = { 0x80, };
  88
  89        bits = cpu_to_be64(sctx->count << 3);
  90
  91        /* Pad out to 56 mod 64 */
  92        index = sctx->count & 0x3f;
  93        padlen = (index < 56) ? (56 - index) : ((64+56) - index);
  94        sha1_update(tfm, padding, padlen);
  95
  96        /* Append length */
  97        sha1_update(tfm, (const u8 *)&bits, sizeof(bits));
  98
  99        /* Store state in digest */
 100        for (i = 0; i < 5; i++)
 101                dst[i] = cpu_to_be32(sctx->state[i]);
 102
 103        /* Wipe context */
 104        memset(sctx, 0, sizeof *sctx);
 105}
 106
 107static struct crypto_alg alg = {
 108        .cra_name       =       "sha1",
 109        .cra_driver_name=       "sha1-generic",
 110        .cra_flags      =       CRYPTO_ALG_TYPE_DIGEST,
 111        .cra_blocksize  =       SHA1_BLOCK_SIZE,
 112        .cra_ctxsize    =       sizeof(struct sha1_ctx),
 113        .cra_module     =       THIS_MODULE,
 114        .cra_alignmask  =       3,
 115        .cra_list       =       LIST_HEAD_INIT(alg.cra_list),
 116        .cra_u          =       { .digest = {
 117        .dia_digestsize =       SHA1_DIGEST_SIZE,
 118        .dia_init       =       sha1_init,
 119        .dia_update     =       sha1_update,
 120        .dia_final      =       sha1_final } }
 121};
 122
 123static int __init sha1_generic_mod_init(void)
 124{
 125        return crypto_register_alg(&alg);
 126}
 127
 128static void __exit sha1_generic_mod_fini(void)
 129{
 130        crypto_unregister_alg(&alg);
 131}
 132
 133module_init(sha1_generic_mod_init);
 134module_exit(sha1_generic_mod_fini);
 135
 136MODULE_LICENSE("GPL");
 137MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");
 138
 139MODULE_ALIAS("sha1");
 140