Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 
0003 #include <crypto/curve25519.h>
0004 #include <crypto/internal/kpp.h>
0005 #include <crypto/kpp.h>
0006 #include <linux/module.h>
0007 #include <linux/scatterlist.h>
0008 
0009 static int curve25519_set_secret(struct crypto_kpp *tfm, const void *buf,
0010                  unsigned int len)
0011 {
0012     u8 *secret = kpp_tfm_ctx(tfm);
0013 
0014     if (!len)
0015         curve25519_generate_secret(secret);
0016     else if (len == CURVE25519_KEY_SIZE &&
0017          crypto_memneq(buf, curve25519_null_point, CURVE25519_KEY_SIZE))
0018         memcpy(secret, buf, CURVE25519_KEY_SIZE);
0019     else
0020         return -EINVAL;
0021     return 0;
0022 }
0023 
0024 static int curve25519_compute_value(struct kpp_request *req)
0025 {
0026     struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
0027     const u8 *secret = kpp_tfm_ctx(tfm);
0028     u8 public_key[CURVE25519_KEY_SIZE];
0029     u8 buf[CURVE25519_KEY_SIZE];
0030     int copied, nbytes;
0031     u8 const *bp;
0032 
0033     if (req->src) {
0034         copied = sg_copy_to_buffer(req->src,
0035                        sg_nents_for_len(req->src,
0036                                 CURVE25519_KEY_SIZE),
0037                        public_key, CURVE25519_KEY_SIZE);
0038         if (copied != CURVE25519_KEY_SIZE)
0039             return -EINVAL;
0040         bp = public_key;
0041     } else {
0042         bp = curve25519_base_point;
0043     }
0044 
0045     curve25519_generic(buf, secret, bp);
0046 
0047     /* might want less than we've got */
0048     nbytes = min_t(size_t, CURVE25519_KEY_SIZE, req->dst_len);
0049     copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst,
0050                                 nbytes),
0051                      buf, nbytes);
0052     if (copied != nbytes)
0053         return -EINVAL;
0054     return 0;
0055 }
0056 
0057 static unsigned int curve25519_max_size(struct crypto_kpp *tfm)
0058 {
0059     return CURVE25519_KEY_SIZE;
0060 }
0061 
0062 static struct kpp_alg curve25519_alg = {
0063     .base.cra_name      = "curve25519",
0064     .base.cra_driver_name   = "curve25519-generic",
0065     .base.cra_priority  = 100,
0066     .base.cra_module    = THIS_MODULE,
0067     .base.cra_ctxsize   = CURVE25519_KEY_SIZE,
0068 
0069     .set_secret     = curve25519_set_secret,
0070     .generate_public_key    = curve25519_compute_value,
0071     .compute_shared_secret  = curve25519_compute_value,
0072     .max_size       = curve25519_max_size,
0073 };
0074 
0075 static int curve25519_init(void)
0076 {
0077     return crypto_register_kpp(&curve25519_alg);
0078 }
0079 
0080 static void curve25519_exit(void)
0081 {
0082     crypto_unregister_kpp(&curve25519_alg);
0083 }
0084 
0085 subsys_initcall(curve25519_init);
0086 module_exit(curve25519_exit);
0087 
0088 MODULE_ALIAS_CRYPTO("curve25519");
0089 MODULE_ALIAS_CRYPTO("curve25519-generic");
0090 MODULE_LICENSE("GPL");