LCOV - code coverage report
Current view: top level - crypto - cipher.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 0 42 0.0 %
Date: 2021-04-22 12:43:58 Functions: 0 5 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /*
       3             :  * Cryptographic API.
       4             :  *
       5             :  * Single-block cipher operations.
       6             :  *
       7             :  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
       8             :  * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
       9             :  */
      10             : 
      11             : #include <crypto/algapi.h>
      12             : #include <crypto/internal/cipher.h>
      13             : #include <linux/kernel.h>
      14             : #include <linux/crypto.h>
      15             : #include <linux/errno.h>
      16             : #include <linux/slab.h>
      17             : #include <linux/string.h>
      18             : #include "internal.h"
      19             : 
      20           0 : static int setkey_unaligned(struct crypto_cipher *tfm, const u8 *key,
      21             :                             unsigned int keylen)
      22             : {
      23           0 :         struct cipher_alg *cia = crypto_cipher_alg(tfm);
      24           0 :         unsigned long alignmask = crypto_cipher_alignmask(tfm);
      25           0 :         int ret;
      26           0 :         u8 *buffer, *alignbuffer;
      27           0 :         unsigned long absize;
      28             : 
      29           0 :         absize = keylen + alignmask;
      30           0 :         buffer = kmalloc(absize, GFP_ATOMIC);
      31           0 :         if (!buffer)
      32             :                 return -ENOMEM;
      33             : 
      34           0 :         alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
      35           0 :         memcpy(alignbuffer, key, keylen);
      36           0 :         ret = cia->cia_setkey(crypto_cipher_tfm(tfm), alignbuffer, keylen);
      37           0 :         memset(alignbuffer, 0, keylen);
      38           0 :         kfree(buffer);
      39           0 :         return ret;
      40             : 
      41             : }
      42             : 
      43           0 : int crypto_cipher_setkey(struct crypto_cipher *tfm,
      44             :                          const u8 *key, unsigned int keylen)
      45             : {
      46           0 :         struct cipher_alg *cia = crypto_cipher_alg(tfm);
      47           0 :         unsigned long alignmask = crypto_cipher_alignmask(tfm);
      48             : 
      49           0 :         if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize)
      50             :                 return -EINVAL;
      51             : 
      52           0 :         if ((unsigned long)key & alignmask)
      53           0 :                 return setkey_unaligned(tfm, key, keylen);
      54             : 
      55           0 :         return cia->cia_setkey(crypto_cipher_tfm(tfm), key, keylen);
      56             : }
      57             : EXPORT_SYMBOL_NS_GPL(crypto_cipher_setkey, CRYPTO_INTERNAL);
      58             : 
      59           0 : static inline void cipher_crypt_one(struct crypto_cipher *tfm,
      60             :                                     u8 *dst, const u8 *src, bool enc)
      61             : {
      62           0 :         unsigned long alignmask = crypto_cipher_alignmask(tfm);
      63           0 :         struct cipher_alg *cia = crypto_cipher_alg(tfm);
      64           0 :         void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
      65           0 :                 enc ? cia->cia_encrypt : cia->cia_decrypt;
      66             : 
      67           0 :         if (unlikely(((unsigned long)dst | (unsigned long)src) & alignmask)) {
      68           0 :                 unsigned int bs = crypto_cipher_blocksize(tfm);
      69           0 :                 u8 buffer[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK];
      70           0 :                 u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
      71             : 
      72           0 :                 memcpy(tmp, src, bs);
      73           0 :                 fn(crypto_cipher_tfm(tfm), tmp, tmp);
      74           0 :                 memcpy(dst, tmp, bs);
      75             :         } else {
      76           0 :                 fn(crypto_cipher_tfm(tfm), dst, src);
      77             :         }
      78           0 : }
      79             : 
      80           0 : void crypto_cipher_encrypt_one(struct crypto_cipher *tfm,
      81             :                                u8 *dst, const u8 *src)
      82             : {
      83           0 :         cipher_crypt_one(tfm, dst, src, true);
      84           0 : }
      85             : EXPORT_SYMBOL_NS_GPL(crypto_cipher_encrypt_one, CRYPTO_INTERNAL);
      86             : 
      87           0 : void crypto_cipher_decrypt_one(struct crypto_cipher *tfm,
      88             :                                u8 *dst, const u8 *src)
      89             : {
      90           0 :         cipher_crypt_one(tfm, dst, src, false);
      91           0 : }
      92             : EXPORT_SYMBOL_NS_GPL(crypto_cipher_decrypt_one, CRYPTO_INTERNAL);

Generated by: LCOV version 1.14