1*58771c1cSSalvatore Benedetto /* 2*58771c1cSSalvatore Benedetto * ECDH helper functions - KPP wrappings 3*58771c1cSSalvatore Benedetto * 4*58771c1cSSalvatore Benedetto * Copyright (C) 2017 Intel Corporation 5*58771c1cSSalvatore Benedetto * 6*58771c1cSSalvatore Benedetto * This program is free software; you can redistribute it and/or modify 7*58771c1cSSalvatore Benedetto * it under the terms of the GNU General Public License version 2 as 8*58771c1cSSalvatore Benedetto * published by the Free Software Foundation; 9*58771c1cSSalvatore Benedetto * 10*58771c1cSSalvatore Benedetto * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 11*58771c1cSSalvatore Benedetto * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 12*58771c1cSSalvatore Benedetto * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 13*58771c1cSSalvatore Benedetto * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 14*58771c1cSSalvatore Benedetto * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 15*58771c1cSSalvatore Benedetto * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16*58771c1cSSalvatore Benedetto * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17*58771c1cSSalvatore Benedetto * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18*58771c1cSSalvatore Benedetto * 19*58771c1cSSalvatore Benedetto * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 20*58771c1cSSalvatore Benedetto * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 21*58771c1cSSalvatore Benedetto * SOFTWARE IS DISCLAIMED. 22*58771c1cSSalvatore Benedetto */ 23*58771c1cSSalvatore Benedetto #include "ecdh_helper.h" 24*58771c1cSSalvatore Benedetto 25*58771c1cSSalvatore Benedetto #include <linux/random.h> 26*58771c1cSSalvatore Benedetto #include <linux/scatterlist.h> 27*58771c1cSSalvatore Benedetto #include <crypto/kpp.h> 28*58771c1cSSalvatore Benedetto #include <crypto/ecdh.h> 29*58771c1cSSalvatore Benedetto 30*58771c1cSSalvatore Benedetto struct ecdh_completion { 31*58771c1cSSalvatore Benedetto struct completion completion; 32*58771c1cSSalvatore Benedetto int err; 33*58771c1cSSalvatore Benedetto }; 34*58771c1cSSalvatore Benedetto 35*58771c1cSSalvatore Benedetto static void ecdh_complete(struct crypto_async_request *req, int err) 36*58771c1cSSalvatore Benedetto { 37*58771c1cSSalvatore Benedetto struct ecdh_completion *res = req->data; 38*58771c1cSSalvatore Benedetto 39*58771c1cSSalvatore Benedetto if (err == -EINPROGRESS) 40*58771c1cSSalvatore Benedetto return; 41*58771c1cSSalvatore Benedetto 42*58771c1cSSalvatore Benedetto res->err = err; 43*58771c1cSSalvatore Benedetto complete(&res->completion); 44*58771c1cSSalvatore Benedetto } 45*58771c1cSSalvatore Benedetto 46*58771c1cSSalvatore Benedetto static inline void swap_digits(u64 *in, u64 *out, unsigned int ndigits) 47*58771c1cSSalvatore Benedetto { 48*58771c1cSSalvatore Benedetto int i; 49*58771c1cSSalvatore Benedetto 50*58771c1cSSalvatore Benedetto for (i = 0; i < ndigits; i++) 51*58771c1cSSalvatore Benedetto out[i] = __swab64(in[ndigits - 1 - i]); 52*58771c1cSSalvatore Benedetto } 53*58771c1cSSalvatore Benedetto 54*58771c1cSSalvatore Benedetto bool compute_ecdh_secret(const u8 public_key[64], const u8 private_key[32], 55*58771c1cSSalvatore Benedetto u8 secret[32]) 56*58771c1cSSalvatore Benedetto { 57*58771c1cSSalvatore Benedetto struct crypto_kpp *tfm; 58*58771c1cSSalvatore Benedetto struct kpp_request *req; 59*58771c1cSSalvatore Benedetto struct ecdh p; 60*58771c1cSSalvatore Benedetto struct ecdh_completion result; 61*58771c1cSSalvatore Benedetto struct scatterlist src, dst; 62*58771c1cSSalvatore Benedetto u8 tmp[64]; 63*58771c1cSSalvatore Benedetto u8 *buf; 64*58771c1cSSalvatore Benedetto unsigned int buf_len; 65*58771c1cSSalvatore Benedetto int err = -ENOMEM; 66*58771c1cSSalvatore Benedetto 67*58771c1cSSalvatore Benedetto tfm = crypto_alloc_kpp("ecdh", CRYPTO_ALG_INTERNAL, 0); 68*58771c1cSSalvatore Benedetto if (IS_ERR(tfm)) { 69*58771c1cSSalvatore Benedetto pr_err("alg: kpp: Failed to load tfm for kpp: %ld\n", 70*58771c1cSSalvatore Benedetto PTR_ERR(tfm)); 71*58771c1cSSalvatore Benedetto return false; 72*58771c1cSSalvatore Benedetto } 73*58771c1cSSalvatore Benedetto 74*58771c1cSSalvatore Benedetto req = kpp_request_alloc(tfm, GFP_KERNEL); 75*58771c1cSSalvatore Benedetto if (!req) 76*58771c1cSSalvatore Benedetto goto free_kpp; 77*58771c1cSSalvatore Benedetto 78*58771c1cSSalvatore Benedetto init_completion(&result.completion); 79*58771c1cSSalvatore Benedetto 80*58771c1cSSalvatore Benedetto /* Security Manager Protocol holds digits in litte-endian order 81*58771c1cSSalvatore Benedetto * while ECC API expect big-endian data 82*58771c1cSSalvatore Benedetto */ 83*58771c1cSSalvatore Benedetto swap_digits((u64 *)private_key, (u64 *)tmp, 4); 84*58771c1cSSalvatore Benedetto p.key = (char *)tmp; 85*58771c1cSSalvatore Benedetto p.key_size = 32; 86*58771c1cSSalvatore Benedetto /* Set curve_id */ 87*58771c1cSSalvatore Benedetto p.curve_id = ECC_CURVE_NIST_P256; 88*58771c1cSSalvatore Benedetto buf_len = crypto_ecdh_key_len(&p); 89*58771c1cSSalvatore Benedetto buf = kmalloc(buf_len, GFP_KERNEL); 90*58771c1cSSalvatore Benedetto if (!buf) { 91*58771c1cSSalvatore Benedetto pr_err("alg: kpp: Failed to allocate %d bytes for buf\n", 92*58771c1cSSalvatore Benedetto buf_len); 93*58771c1cSSalvatore Benedetto goto free_req; 94*58771c1cSSalvatore Benedetto } 95*58771c1cSSalvatore Benedetto crypto_ecdh_encode_key(buf, buf_len, &p); 96*58771c1cSSalvatore Benedetto 97*58771c1cSSalvatore Benedetto /* Set A private Key */ 98*58771c1cSSalvatore Benedetto err = crypto_kpp_set_secret(tfm, (void *)buf, buf_len); 99*58771c1cSSalvatore Benedetto if (err) 100*58771c1cSSalvatore Benedetto goto free_all; 101*58771c1cSSalvatore Benedetto 102*58771c1cSSalvatore Benedetto swap_digits((u64 *)public_key, (u64 *)tmp, 4); /* x */ 103*58771c1cSSalvatore Benedetto swap_digits((u64 *)&public_key[32], (u64 *)&tmp[32], 4); /* y */ 104*58771c1cSSalvatore Benedetto 105*58771c1cSSalvatore Benedetto sg_init_one(&src, tmp, 64); 106*58771c1cSSalvatore Benedetto sg_init_one(&dst, secret, 32); 107*58771c1cSSalvatore Benedetto kpp_request_set_input(req, &src, 64); 108*58771c1cSSalvatore Benedetto kpp_request_set_output(req, &dst, 32); 109*58771c1cSSalvatore Benedetto kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 110*58771c1cSSalvatore Benedetto ecdh_complete, &result); 111*58771c1cSSalvatore Benedetto err = crypto_kpp_compute_shared_secret(req); 112*58771c1cSSalvatore Benedetto if (err == -EINPROGRESS) { 113*58771c1cSSalvatore Benedetto wait_for_completion(&result.completion); 114*58771c1cSSalvatore Benedetto err = result.err; 115*58771c1cSSalvatore Benedetto } 116*58771c1cSSalvatore Benedetto if (err < 0) { 117*58771c1cSSalvatore Benedetto pr_err("alg: ecdh: compute shared secret failed. err %d\n", 118*58771c1cSSalvatore Benedetto err); 119*58771c1cSSalvatore Benedetto goto free_all; 120*58771c1cSSalvatore Benedetto } 121*58771c1cSSalvatore Benedetto 122*58771c1cSSalvatore Benedetto swap_digits((u64 *)secret, (u64 *)tmp, 4); 123*58771c1cSSalvatore Benedetto memcpy(secret, tmp, 32); 124*58771c1cSSalvatore Benedetto 125*58771c1cSSalvatore Benedetto free_all: 126*58771c1cSSalvatore Benedetto kzfree(buf); 127*58771c1cSSalvatore Benedetto free_req: 128*58771c1cSSalvatore Benedetto kpp_request_free(req); 129*58771c1cSSalvatore Benedetto free_kpp: 130*58771c1cSSalvatore Benedetto crypto_free_kpp(tfm); 131*58771c1cSSalvatore Benedetto return (err == 0); 132*58771c1cSSalvatore Benedetto } 133*58771c1cSSalvatore Benedetto 134*58771c1cSSalvatore Benedetto bool generate_ecdh_keys(u8 public_key[64], u8 private_key[32]) 135*58771c1cSSalvatore Benedetto { 136*58771c1cSSalvatore Benedetto struct crypto_kpp *tfm; 137*58771c1cSSalvatore Benedetto struct kpp_request *req; 138*58771c1cSSalvatore Benedetto struct ecdh p; 139*58771c1cSSalvatore Benedetto struct ecdh_completion result; 140*58771c1cSSalvatore Benedetto struct scatterlist dst; 141*58771c1cSSalvatore Benedetto u8 tmp[64]; 142*58771c1cSSalvatore Benedetto u8 *buf; 143*58771c1cSSalvatore Benedetto unsigned int buf_len; 144*58771c1cSSalvatore Benedetto int err = -ENOMEM; 145*58771c1cSSalvatore Benedetto const unsigned short max_tries = 16; 146*58771c1cSSalvatore Benedetto unsigned short tries = 0; 147*58771c1cSSalvatore Benedetto 148*58771c1cSSalvatore Benedetto tfm = crypto_alloc_kpp("ecdh", CRYPTO_ALG_INTERNAL, 0); 149*58771c1cSSalvatore Benedetto if (IS_ERR(tfm)) { 150*58771c1cSSalvatore Benedetto pr_err("alg: kpp: Failed to load tfm for kpp: %ld\n", 151*58771c1cSSalvatore Benedetto PTR_ERR(tfm)); 152*58771c1cSSalvatore Benedetto return false; 153*58771c1cSSalvatore Benedetto } 154*58771c1cSSalvatore Benedetto 155*58771c1cSSalvatore Benedetto req = kpp_request_alloc(tfm, GFP_KERNEL); 156*58771c1cSSalvatore Benedetto if (!req) 157*58771c1cSSalvatore Benedetto goto free_kpp; 158*58771c1cSSalvatore Benedetto 159*58771c1cSSalvatore Benedetto init_completion(&result.completion); 160*58771c1cSSalvatore Benedetto 161*58771c1cSSalvatore Benedetto /* Set curve_id */ 162*58771c1cSSalvatore Benedetto p.curve_id = ECC_CURVE_NIST_P256; 163*58771c1cSSalvatore Benedetto p.key_size = 32; 164*58771c1cSSalvatore Benedetto buf_len = crypto_ecdh_key_len(&p); 165*58771c1cSSalvatore Benedetto buf = kmalloc(buf_len, GFP_KERNEL); 166*58771c1cSSalvatore Benedetto if (!buf) { 167*58771c1cSSalvatore Benedetto pr_err("alg: kpp: Failed to allocate %d bytes for buf\n", 168*58771c1cSSalvatore Benedetto buf_len); 169*58771c1cSSalvatore Benedetto goto free_req; 170*58771c1cSSalvatore Benedetto } 171*58771c1cSSalvatore Benedetto 172*58771c1cSSalvatore Benedetto do { 173*58771c1cSSalvatore Benedetto if (tries++ >= max_tries) 174*58771c1cSSalvatore Benedetto goto free_all; 175*58771c1cSSalvatore Benedetto 176*58771c1cSSalvatore Benedetto get_random_bytes(private_key, 32); 177*58771c1cSSalvatore Benedetto 178*58771c1cSSalvatore Benedetto /* Set private Key */ 179*58771c1cSSalvatore Benedetto p.key = (char *)private_key; 180*58771c1cSSalvatore Benedetto crypto_ecdh_encode_key(buf, buf_len, &p); 181*58771c1cSSalvatore Benedetto err = crypto_kpp_set_secret(tfm, buf, buf_len); 182*58771c1cSSalvatore Benedetto if (err) 183*58771c1cSSalvatore Benedetto goto free_all; 184*58771c1cSSalvatore Benedetto 185*58771c1cSSalvatore Benedetto sg_init_one(&dst, tmp, 64); 186*58771c1cSSalvatore Benedetto kpp_request_set_output(req, &dst, 64); 187*58771c1cSSalvatore Benedetto kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 188*58771c1cSSalvatore Benedetto ecdh_complete, &result); 189*58771c1cSSalvatore Benedetto 190*58771c1cSSalvatore Benedetto err = crypto_kpp_generate_public_key(req); 191*58771c1cSSalvatore Benedetto 192*58771c1cSSalvatore Benedetto if (err == -EINPROGRESS) { 193*58771c1cSSalvatore Benedetto wait_for_completion(&result.completion); 194*58771c1cSSalvatore Benedetto err = result.err; 195*58771c1cSSalvatore Benedetto } 196*58771c1cSSalvatore Benedetto 197*58771c1cSSalvatore Benedetto /* Private key is not valid. Regenerate */ 198*58771c1cSSalvatore Benedetto if (err == -EINVAL) 199*58771c1cSSalvatore Benedetto continue; 200*58771c1cSSalvatore Benedetto 201*58771c1cSSalvatore Benedetto if (err < 0) 202*58771c1cSSalvatore Benedetto goto free_all; 203*58771c1cSSalvatore Benedetto else 204*58771c1cSSalvatore Benedetto break; 205*58771c1cSSalvatore Benedetto 206*58771c1cSSalvatore Benedetto } while (true); 207*58771c1cSSalvatore Benedetto 208*58771c1cSSalvatore Benedetto /* Keys are handed back in little endian as expected by Security 209*58771c1cSSalvatore Benedetto * Manager Protocol 210*58771c1cSSalvatore Benedetto */ 211*58771c1cSSalvatore Benedetto swap_digits((u64 *)tmp, (u64 *)public_key, 4); /* x */ 212*58771c1cSSalvatore Benedetto swap_digits((u64 *)&tmp[32], (u64 *)&public_key[32], 4); /* y */ 213*58771c1cSSalvatore Benedetto swap_digits((u64 *)private_key, (u64 *)tmp, 4); 214*58771c1cSSalvatore Benedetto memcpy(private_key, tmp, 32); 215*58771c1cSSalvatore Benedetto 216*58771c1cSSalvatore Benedetto free_all: 217*58771c1cSSalvatore Benedetto kzfree(buf); 218*58771c1cSSalvatore Benedetto free_req: 219*58771c1cSSalvatore Benedetto kpp_request_free(req); 220*58771c1cSSalvatore Benedetto free_kpp: 221*58771c1cSSalvatore Benedetto crypto_free_kpp(tfm); 222*58771c1cSSalvatore Benedetto return (err == 0); 223*58771c1cSSalvatore Benedetto } 224