linux/crypto/curve25519-generic.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2
   3#include <crypto/curve25519.h>
   4#include <crypto/internal/kpp.h>
   5#include <crypto/kpp.h>
   6#include <linux/module.h>
   7#include <linux/scatterlist.h>
   8
   9static int curve25519_set_secret(struct crypto_kpp *tfm, const void *buf,
  10                                 unsigned int len)
  11{
  12        u8 *secret = kpp_tfm_ctx(tfm);
  13
  14        if (!len)
  15                curve25519_generate_secret(secret);
  16        else if (len == CURVE25519_KEY_SIZE &&
  17                 crypto_memneq(buf, curve25519_null_point, CURVE25519_KEY_SIZE))
  18                memcpy(secret, buf, CURVE25519_KEY_SIZE);
  19        else
  20                return -EINVAL;
  21        return 0;
  22}
  23
  24static int curve25519_compute_value(struct kpp_request *req)
  25{
  26        struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
  27        const u8 *secret = kpp_tfm_ctx(tfm);
  28        u8 public_key[CURVE25519_KEY_SIZE];
  29        u8 buf[CURVE25519_KEY_SIZE];
  30        int copied, nbytes;
  31        u8 const *bp;
  32
  33        if (req->src) {
  34                copied = sg_copy_to_buffer(req->src,
  35                                           sg_nents_for_len(req->src,
  36                                                            CURVE25519_KEY_SIZE),
  37                                           public_key, CURVE25519_KEY_SIZE);
  38                if (copied != CURVE25519_KEY_SIZE)
  39                        return -EINVAL;
  40                bp = public_key;
  41        } else {
  42                bp = curve25519_base_point;
  43        }
  44
  45        curve25519_generic(buf, secret, bp);
  46
  47        /* might want less than we've got */
  48        nbytes = min_t(size_t, CURVE25519_KEY_SIZE, req->dst_len);
  49        copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst,
  50                                                                nbytes),
  51                                     buf, nbytes);
  52        if (copied != nbytes)
  53                return -EINVAL;
  54        return 0;
  55}
  56
  57static unsigned int curve25519_max_size(struct crypto_kpp *tfm)
  58{
  59        return CURVE25519_KEY_SIZE;
  60}
  61
  62static struct kpp_alg curve25519_alg = {
  63        .base.cra_name          = "curve25519",
  64        .base.cra_driver_name   = "curve25519-generic",
  65        .base.cra_priority      = 100,
  66        .base.cra_module        = THIS_MODULE,
  67        .base.cra_ctxsize       = CURVE25519_KEY_SIZE,
  68
  69        .set_secret             = curve25519_set_secret,
  70        .generate_public_key    = curve25519_compute_value,
  71        .compute_shared_secret  = curve25519_compute_value,
  72        .max_size               = curve25519_max_size,
  73};
  74
  75static int curve25519_init(void)
  76{
  77        return crypto_register_kpp(&curve25519_alg);
  78}
  79
  80static void curve25519_exit(void)
  81{
  82        crypto_unregister_kpp(&curve25519_alg);
  83}
  84
  85subsys_initcall(curve25519_init);
  86module_exit(curve25519_exit);
  87
  88MODULE_ALIAS_CRYPTO("curve25519");
  89MODULE_ALIAS_CRYPTO("curve25519-generic");
  90MODULE_LICENSE("GPL");
  91