root/crypto/ofb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. crypto_ofb_crypt
  2. crypto_ofb_create
  3. crypto_ofb_module_init
  4. crypto_ofb_module_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 
   3 /*
   4  * OFB: Output FeedBack mode
   5  *
   6  * Copyright (C) 2018 ARM Limited or its affiliates.
   7  * All rights reserved.
   8  */
   9 
  10 #include <crypto/algapi.h>
  11 #include <crypto/internal/skcipher.h>
  12 #include <linux/err.h>
  13 #include <linux/init.h>
  14 #include <linux/kernel.h>
  15 #include <linux/module.h>
  16 
  17 static int crypto_ofb_crypt(struct skcipher_request *req)
  18 {
  19         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
  20         struct crypto_cipher *cipher = skcipher_cipher_simple(tfm);
  21         const unsigned int bsize = crypto_cipher_blocksize(cipher);
  22         struct skcipher_walk walk;
  23         int err;
  24 
  25         err = skcipher_walk_virt(&walk, req, false);
  26 
  27         while (walk.nbytes >= bsize) {
  28                 const u8 *src = walk.src.virt.addr;
  29                 u8 *dst = walk.dst.virt.addr;
  30                 u8 * const iv = walk.iv;
  31                 unsigned int nbytes = walk.nbytes;
  32 
  33                 do {
  34                         crypto_cipher_encrypt_one(cipher, iv, iv);
  35                         crypto_xor_cpy(dst, src, iv, bsize);
  36                         dst += bsize;
  37                         src += bsize;
  38                 } while ((nbytes -= bsize) >= bsize);
  39 
  40                 err = skcipher_walk_done(&walk, nbytes);
  41         }
  42 
  43         if (walk.nbytes) {
  44                 crypto_cipher_encrypt_one(cipher, walk.iv, walk.iv);
  45                 crypto_xor_cpy(walk.dst.virt.addr, walk.src.virt.addr, walk.iv,
  46                                walk.nbytes);
  47                 err = skcipher_walk_done(&walk, 0);
  48         }
  49         return err;
  50 }
  51 
  52 static int crypto_ofb_create(struct crypto_template *tmpl, struct rtattr **tb)
  53 {
  54         struct skcipher_instance *inst;
  55         struct crypto_alg *alg;
  56         int err;
  57 
  58         inst = skcipher_alloc_instance_simple(tmpl, tb, &alg);
  59         if (IS_ERR(inst))
  60                 return PTR_ERR(inst);
  61 
  62         /* OFB mode is a stream cipher. */
  63         inst->alg.base.cra_blocksize = 1;
  64 
  65         /*
  66          * To simplify the implementation, configure the skcipher walk to only
  67          * give a partial block at the very end, never earlier.
  68          */
  69         inst->alg.chunksize = alg->cra_blocksize;
  70 
  71         inst->alg.encrypt = crypto_ofb_crypt;
  72         inst->alg.decrypt = crypto_ofb_crypt;
  73 
  74         err = skcipher_register_instance(tmpl, inst);
  75         if (err)
  76                 inst->free(inst);
  77 
  78         crypto_mod_put(alg);
  79         return err;
  80 }
  81 
  82 static struct crypto_template crypto_ofb_tmpl = {
  83         .name = "ofb",
  84         .create = crypto_ofb_create,
  85         .module = THIS_MODULE,
  86 };
  87 
  88 static int __init crypto_ofb_module_init(void)
  89 {
  90         return crypto_register_template(&crypto_ofb_tmpl);
  91 }
  92 
  93 static void __exit crypto_ofb_module_exit(void)
  94 {
  95         crypto_unregister_template(&crypto_ofb_tmpl);
  96 }
  97 
  98 subsys_initcall(crypto_ofb_module_init);
  99 module_exit(crypto_ofb_module_exit);
 100 
 101 MODULE_LICENSE("GPL");
 102 MODULE_DESCRIPTION("OFB block cipher mode of operation");
 103 MODULE_ALIAS_CRYPTO("ofb");

/* [<][>][^][v][top][bottom][index][help] */