linux/include/crypto/internal/blake2s.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 OR MIT */
   2/*
   3 * Helper functions for BLAKE2s implementations.
   4 * Keep this in sync with the corresponding BLAKE2b header.
   5 */
   6
   7#ifndef _CRYPTO_INTERNAL_BLAKE2S_H
   8#define _CRYPTO_INTERNAL_BLAKE2S_H
   9
  10#include <crypto/blake2s.h>
  11#include <crypto/internal/hash.h>
  12#include <linux/string.h>
  13
  14void blake2s_compress_generic(struct blake2s_state *state,const u8 *block,
  15                              size_t nblocks, const u32 inc);
  16
  17void blake2s_compress_arch(struct blake2s_state *state,const u8 *block,
  18                           size_t nblocks, const u32 inc);
  19
  20bool blake2s_selftest(void);
  21
  22static inline void blake2s_set_lastblock(struct blake2s_state *state)
  23{
  24        state->f[0] = -1;
  25}
  26
  27typedef void (*blake2s_compress_t)(struct blake2s_state *state,
  28                                   const u8 *block, size_t nblocks, u32 inc);
  29
  30/* Helper functions for BLAKE2s shared by the library and shash APIs */
  31
  32static inline void __blake2s_update(struct blake2s_state *state,
  33                                    const u8 *in, size_t inlen,
  34                                    blake2s_compress_t compress)
  35{
  36        const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;
  37
  38        if (unlikely(!inlen))
  39                return;
  40        if (inlen > fill) {
  41                memcpy(state->buf + state->buflen, in, fill);
  42                (*compress)(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
  43                state->buflen = 0;
  44                in += fill;
  45                inlen -= fill;
  46        }
  47        if (inlen > BLAKE2S_BLOCK_SIZE) {
  48                const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
  49                /* Hash one less (full) block than strictly possible */
  50                (*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
  51                in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
  52                inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
  53        }
  54        memcpy(state->buf + state->buflen, in, inlen);
  55        state->buflen += inlen;
  56}
  57
  58static inline void __blake2s_final(struct blake2s_state *state, u8 *out,
  59                                   blake2s_compress_t compress)
  60{
  61        blake2s_set_lastblock(state);
  62        memset(state->buf + state->buflen, 0,
  63               BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
  64        (*compress)(state, state->buf, 1, state->buflen);
  65        cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
  66        memcpy(out, state->h, state->outlen);
  67}
  68
  69/* Helper functions for shash implementations of BLAKE2s */
  70
  71struct blake2s_tfm_ctx {
  72        u8 key[BLAKE2S_KEY_SIZE];
  73        unsigned int keylen;
  74};
  75
  76static inline int crypto_blake2s_setkey(struct crypto_shash *tfm,
  77                                        const u8 *key, unsigned int keylen)
  78{
  79        struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(tfm);
  80
  81        if (keylen == 0 || keylen > BLAKE2S_KEY_SIZE)
  82                return -EINVAL;
  83
  84        memcpy(tctx->key, key, keylen);
  85        tctx->keylen = keylen;
  86
  87        return 0;
  88}
  89
  90static inline int crypto_blake2s_init(struct shash_desc *desc)
  91{
  92        const struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
  93        struct blake2s_state *state = shash_desc_ctx(desc);
  94        unsigned int outlen = crypto_shash_digestsize(desc->tfm);
  95
  96        __blake2s_init(state, outlen, tctx->key, tctx->keylen);
  97        return 0;
  98}
  99
 100static inline int crypto_blake2s_update(struct shash_desc *desc,
 101                                        const u8 *in, unsigned int inlen,
 102                                        blake2s_compress_t compress)
 103{
 104        struct blake2s_state *state = shash_desc_ctx(desc);
 105
 106        __blake2s_update(state, in, inlen, compress);
 107        return 0;
 108}
 109
 110static inline int crypto_blake2s_final(struct shash_desc *desc, u8 *out,
 111                                       blake2s_compress_t compress)
 112{
 113        struct blake2s_state *state = shash_desc_ctx(desc);
 114
 115        __blake2s_final(state, out, compress);
 116        return 0;
 117}
 118
 119#endif /* _CRYPTO_INTERNAL_BLAKE2S_H */
 120