linux/include/crypto/chacha.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * Common values and helper functions for the ChaCha and XChaCha stream ciphers.
   4 *
   5 * XChaCha extends ChaCha's nonce to 192 bits, while provably retaining ChaCha's
   6 * security.  Here they share the same key size, tfm context, and setkey
   7 * function; only their IV size and encrypt/decrypt function differ.
   8 *
   9 * The ChaCha paper specifies 20, 12, and 8-round variants.  In general, it is
  10 * recommended to use the 20-round variant ChaCha20.  However, the other
  11 * variants can be needed in some performance-sensitive scenarios.  The generic
  12 * ChaCha code currently allows only the 20 and 12-round variants.
  13 */
  14
  15#ifndef _CRYPTO_CHACHA_H
  16#define _CRYPTO_CHACHA_H
  17
  18#include <asm/unaligned.h>
  19#include <linux/types.h>
  20
  21/* 32-bit stream position, then 96-bit nonce (RFC7539 convention) */
  22#define CHACHA_IV_SIZE          16
  23
  24#define CHACHA_KEY_SIZE         32
  25#define CHACHA_BLOCK_SIZE       64
  26#define CHACHAPOLY_IV_SIZE      12
  27
  28#define CHACHA_STATE_WORDS      (CHACHA_BLOCK_SIZE / sizeof(u32))
  29
  30/* 192-bit nonce, then 64-bit stream position */
  31#define XCHACHA_IV_SIZE         32
  32
  33void chacha_block_generic(u32 *state, u8 *stream, int nrounds);
  34static inline void chacha20_block(u32 *state, u8 *stream)
  35{
  36        chacha_block_generic(state, stream, 20);
  37}
  38
  39void hchacha_block_arch(const u32 *state, u32 *out, int nrounds);
  40void hchacha_block_generic(const u32 *state, u32 *out, int nrounds);
  41
  42static inline void hchacha_block(const u32 *state, u32 *out, int nrounds)
  43{
  44        if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA))
  45                hchacha_block_arch(state, out, nrounds);
  46        else
  47                hchacha_block_generic(state, out, nrounds);
  48}
  49
  50void chacha_init_arch(u32 *state, const u32 *key, const u8 *iv);
  51static inline void chacha_init_generic(u32 *state, const u32 *key, const u8 *iv)
  52{
  53        state[0]  = 0x61707865; /* "expa" */
  54        state[1]  = 0x3320646e; /* "nd 3" */
  55        state[2]  = 0x79622d32; /* "2-by" */
  56        state[3]  = 0x6b206574; /* "te k" */
  57        state[4]  = key[0];
  58        state[5]  = key[1];
  59        state[6]  = key[2];
  60        state[7]  = key[3];
  61        state[8]  = key[4];
  62        state[9]  = key[5];
  63        state[10] = key[6];
  64        state[11] = key[7];
  65        state[12] = get_unaligned_le32(iv +  0);
  66        state[13] = get_unaligned_le32(iv +  4);
  67        state[14] = get_unaligned_le32(iv +  8);
  68        state[15] = get_unaligned_le32(iv + 12);
  69}
  70
  71static inline void chacha_init(u32 *state, const u32 *key, const u8 *iv)
  72{
  73        if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA))
  74                chacha_init_arch(state, key, iv);
  75        else
  76                chacha_init_generic(state, key, iv);
  77}
  78
  79void chacha_crypt_arch(u32 *state, u8 *dst, const u8 *src,
  80                       unsigned int bytes, int nrounds);
  81void chacha_crypt_generic(u32 *state, u8 *dst, const u8 *src,
  82                          unsigned int bytes, int nrounds);
  83
  84static inline void chacha_crypt(u32 *state, u8 *dst, const u8 *src,
  85                                unsigned int bytes, int nrounds)
  86{
  87        if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA))
  88                chacha_crypt_arch(state, dst, src, bytes, nrounds);
  89        else
  90                chacha_crypt_generic(state, dst, src, bytes, nrounds);
  91}
  92
  93static inline void chacha20_crypt(u32 *state, u8 *dst, const u8 *src,
  94                                  unsigned int bytes)
  95{
  96        chacha_crypt(state, dst, src, bytes, 20);
  97}
  98
  99#endif /* _CRYPTO_CHACHA_H */
 100