162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Key Wrapping: RFC3394 / NIST SP800-38F 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 2015, Stephan Mueller <smueller@chronox.de> 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 762306a36Sopenharmony_ci * modification, are permitted provided that the following conditions 862306a36Sopenharmony_ci * are met: 962306a36Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 1062306a36Sopenharmony_ci * notice, and the entire permission notice in its entirety, 1162306a36Sopenharmony_ci * including the disclaimer of warranties. 1262306a36Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 1362306a36Sopenharmony_ci * notice, this list of conditions and the following disclaimer in the 1462306a36Sopenharmony_ci * documentation and/or other materials provided with the distribution. 1562306a36Sopenharmony_ci * 3. The name of the author may not be used to endorse or promote 1662306a36Sopenharmony_ci * products derived from this software without specific prior 1762306a36Sopenharmony_ci * written permission. 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * ALTERNATIVELY, this product may be distributed under the terms of 2062306a36Sopenharmony_ci * the GNU General Public License, in which case the provisions of the GPL2 2162306a36Sopenharmony_ci * are required INSTEAD OF the above restrictions. (This clause is 2262306a36Sopenharmony_ci * necessary due to a potential bad interaction between the GPL and 2362306a36Sopenharmony_ci * the restrictions contained in a BSD-style copyright.) 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 2662306a36Sopenharmony_ci * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2762306a36Sopenharmony_ci * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 2862306a36Sopenharmony_ci * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 2962306a36Sopenharmony_ci * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3062306a36Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 3162306a36Sopenharmony_ci * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 3262306a36Sopenharmony_ci * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3362306a36Sopenharmony_ci * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3462306a36Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 3562306a36Sopenharmony_ci * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 3662306a36Sopenharmony_ci * DAMAGE. 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/* 4062306a36Sopenharmony_ci * Note for using key wrapping: 4162306a36Sopenharmony_ci * 4262306a36Sopenharmony_ci * * The result of the encryption operation is the ciphertext starting 4362306a36Sopenharmony_ci * with the 2nd semiblock. The first semiblock is provided as the IV. 4462306a36Sopenharmony_ci * The IV used to start the encryption operation is the default IV. 4562306a36Sopenharmony_ci * 4662306a36Sopenharmony_ci * * The input for the decryption is the first semiblock handed in as an 4762306a36Sopenharmony_ci * IV. The ciphertext is the data starting with the 2nd semiblock. The 4862306a36Sopenharmony_ci * return code of the decryption operation will be EBADMSG in case an 4962306a36Sopenharmony_ci * integrity error occurs. 5062306a36Sopenharmony_ci * 5162306a36Sopenharmony_ci * To obtain the full result of an encryption as expected by SP800-38F, the 5262306a36Sopenharmony_ci * caller must allocate a buffer of plaintext + 8 bytes: 5362306a36Sopenharmony_ci * 5462306a36Sopenharmony_ci * unsigned int datalen = ptlen + crypto_skcipher_ivsize(tfm); 5562306a36Sopenharmony_ci * u8 data[datalen]; 5662306a36Sopenharmony_ci * u8 *iv = data; 5762306a36Sopenharmony_ci * u8 *pt = data + crypto_skcipher_ivsize(tfm); 5862306a36Sopenharmony_ci * <ensure that pt contains the plaintext of size ptlen> 5962306a36Sopenharmony_ci * sg_init_one(&sg, pt, ptlen); 6062306a36Sopenharmony_ci * skcipher_request_set_crypt(req, &sg, &sg, ptlen, iv); 6162306a36Sopenharmony_ci * 6262306a36Sopenharmony_ci * ==> After encryption, data now contains full KW result as per SP800-38F. 6362306a36Sopenharmony_ci * 6462306a36Sopenharmony_ci * In case of decryption, ciphertext now already has the expected length 6562306a36Sopenharmony_ci * and must be segmented appropriately: 6662306a36Sopenharmony_ci * 6762306a36Sopenharmony_ci * unsigned int datalen = CTLEN; 6862306a36Sopenharmony_ci * u8 data[datalen]; 6962306a36Sopenharmony_ci * <ensure that data contains full ciphertext> 7062306a36Sopenharmony_ci * u8 *iv = data; 7162306a36Sopenharmony_ci * u8 *ct = data + crypto_skcipher_ivsize(tfm); 7262306a36Sopenharmony_ci * unsigned int ctlen = datalen - crypto_skcipher_ivsize(tfm); 7362306a36Sopenharmony_ci * sg_init_one(&sg, ct, ctlen); 7462306a36Sopenharmony_ci * skcipher_request_set_crypt(req, &sg, &sg, ctlen, iv); 7562306a36Sopenharmony_ci * 7662306a36Sopenharmony_ci * ==> After decryption (which hopefully does not return EBADMSG), the ct 7762306a36Sopenharmony_ci * pointer now points to the plaintext of size ctlen. 7862306a36Sopenharmony_ci * 7962306a36Sopenharmony_ci * Note 2: KWP is not implemented as this would defy in-place operation. 8062306a36Sopenharmony_ci * If somebody wants to wrap non-aligned data, he should simply pad 8162306a36Sopenharmony_ci * the input with zeros to fill it up to the 8 byte boundary. 8262306a36Sopenharmony_ci */ 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci#include <linux/module.h> 8562306a36Sopenharmony_ci#include <linux/crypto.h> 8662306a36Sopenharmony_ci#include <linux/scatterlist.h> 8762306a36Sopenharmony_ci#include <crypto/scatterwalk.h> 8862306a36Sopenharmony_ci#include <crypto/internal/cipher.h> 8962306a36Sopenharmony_ci#include <crypto/internal/skcipher.h> 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cistruct crypto_kw_block { 9262306a36Sopenharmony_ci#define SEMIBSIZE 8 9362306a36Sopenharmony_ci __be64 A; 9462306a36Sopenharmony_ci __be64 R; 9562306a36Sopenharmony_ci}; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci/* 9862306a36Sopenharmony_ci * Fast forward the SGL to the "end" length minus SEMIBSIZE. 9962306a36Sopenharmony_ci * The start in the SGL defined by the fast-forward is returned with 10062306a36Sopenharmony_ci * the walk variable 10162306a36Sopenharmony_ci */ 10262306a36Sopenharmony_cistatic void crypto_kw_scatterlist_ff(struct scatter_walk *walk, 10362306a36Sopenharmony_ci struct scatterlist *sg, 10462306a36Sopenharmony_ci unsigned int end) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci unsigned int skip = 0; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci /* The caller should only operate on full SEMIBLOCKs. */ 10962306a36Sopenharmony_ci BUG_ON(end < SEMIBSIZE); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci skip = end - SEMIBSIZE; 11262306a36Sopenharmony_ci while (sg) { 11362306a36Sopenharmony_ci if (sg->length > skip) { 11462306a36Sopenharmony_ci scatterwalk_start(walk, sg); 11562306a36Sopenharmony_ci scatterwalk_advance(walk, skip); 11662306a36Sopenharmony_ci break; 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci skip -= sg->length; 12062306a36Sopenharmony_ci sg = sg_next(sg); 12162306a36Sopenharmony_ci } 12262306a36Sopenharmony_ci} 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistatic int crypto_kw_decrypt(struct skcipher_request *req) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 12762306a36Sopenharmony_ci struct crypto_cipher *cipher = skcipher_cipher_simple(tfm); 12862306a36Sopenharmony_ci struct crypto_kw_block block; 12962306a36Sopenharmony_ci struct scatterlist *src, *dst; 13062306a36Sopenharmony_ci u64 t = 6 * ((req->cryptlen) >> 3); 13162306a36Sopenharmony_ci unsigned int i; 13262306a36Sopenharmony_ci int ret = 0; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci /* 13562306a36Sopenharmony_ci * Require at least 2 semiblocks (note, the 3rd semiblock that is 13662306a36Sopenharmony_ci * required by SP800-38F is the IV. 13762306a36Sopenharmony_ci */ 13862306a36Sopenharmony_ci if (req->cryptlen < (2 * SEMIBSIZE) || req->cryptlen % SEMIBSIZE) 13962306a36Sopenharmony_ci return -EINVAL; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci /* Place the IV into block A */ 14262306a36Sopenharmony_ci memcpy(&block.A, req->iv, SEMIBSIZE); 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci /* 14562306a36Sopenharmony_ci * src scatterlist is read-only. dst scatterlist is r/w. During the 14662306a36Sopenharmony_ci * first loop, src points to req->src and dst to req->dst. For any 14762306a36Sopenharmony_ci * subsequent round, the code operates on req->dst only. 14862306a36Sopenharmony_ci */ 14962306a36Sopenharmony_ci src = req->src; 15062306a36Sopenharmony_ci dst = req->dst; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 15362306a36Sopenharmony_ci struct scatter_walk src_walk, dst_walk; 15462306a36Sopenharmony_ci unsigned int nbytes = req->cryptlen; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci while (nbytes) { 15762306a36Sopenharmony_ci /* move pointer by nbytes in the SGL */ 15862306a36Sopenharmony_ci crypto_kw_scatterlist_ff(&src_walk, src, nbytes); 15962306a36Sopenharmony_ci /* get the source block */ 16062306a36Sopenharmony_ci scatterwalk_copychunks(&block.R, &src_walk, SEMIBSIZE, 16162306a36Sopenharmony_ci false); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci /* perform KW operation: modify IV with counter */ 16462306a36Sopenharmony_ci block.A ^= cpu_to_be64(t); 16562306a36Sopenharmony_ci t--; 16662306a36Sopenharmony_ci /* perform KW operation: decrypt block */ 16762306a36Sopenharmony_ci crypto_cipher_decrypt_one(cipher, (u8 *)&block, 16862306a36Sopenharmony_ci (u8 *)&block); 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci /* move pointer by nbytes in the SGL */ 17162306a36Sopenharmony_ci crypto_kw_scatterlist_ff(&dst_walk, dst, nbytes); 17262306a36Sopenharmony_ci /* Copy block->R into place */ 17362306a36Sopenharmony_ci scatterwalk_copychunks(&block.R, &dst_walk, SEMIBSIZE, 17462306a36Sopenharmony_ci true); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci nbytes -= SEMIBSIZE; 17762306a36Sopenharmony_ci } 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci /* we now start to operate on the dst SGL only */ 18062306a36Sopenharmony_ci src = req->dst; 18162306a36Sopenharmony_ci dst = req->dst; 18262306a36Sopenharmony_ci } 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci /* Perform authentication check */ 18562306a36Sopenharmony_ci if (block.A != cpu_to_be64(0xa6a6a6a6a6a6a6a6ULL)) 18662306a36Sopenharmony_ci ret = -EBADMSG; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci memzero_explicit(&block, sizeof(struct crypto_kw_block)); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci return ret; 19162306a36Sopenharmony_ci} 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_cistatic int crypto_kw_encrypt(struct skcipher_request *req) 19462306a36Sopenharmony_ci{ 19562306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 19662306a36Sopenharmony_ci struct crypto_cipher *cipher = skcipher_cipher_simple(tfm); 19762306a36Sopenharmony_ci struct crypto_kw_block block; 19862306a36Sopenharmony_ci struct scatterlist *src, *dst; 19962306a36Sopenharmony_ci u64 t = 1; 20062306a36Sopenharmony_ci unsigned int i; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci /* 20362306a36Sopenharmony_ci * Require at least 2 semiblocks (note, the 3rd semiblock that is 20462306a36Sopenharmony_ci * required by SP800-38F is the IV that occupies the first semiblock. 20562306a36Sopenharmony_ci * This means that the dst memory must be one semiblock larger than src. 20662306a36Sopenharmony_ci * Also ensure that the given data is aligned to semiblock. 20762306a36Sopenharmony_ci */ 20862306a36Sopenharmony_ci if (req->cryptlen < (2 * SEMIBSIZE) || req->cryptlen % SEMIBSIZE) 20962306a36Sopenharmony_ci return -EINVAL; 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci /* 21262306a36Sopenharmony_ci * Place the predefined IV into block A -- for encrypt, the caller 21362306a36Sopenharmony_ci * does not need to provide an IV, but he needs to fetch the final IV. 21462306a36Sopenharmony_ci */ 21562306a36Sopenharmony_ci block.A = cpu_to_be64(0xa6a6a6a6a6a6a6a6ULL); 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci /* 21862306a36Sopenharmony_ci * src scatterlist is read-only. dst scatterlist is r/w. During the 21962306a36Sopenharmony_ci * first loop, src points to req->src and dst to req->dst. For any 22062306a36Sopenharmony_ci * subsequent round, the code operates on req->dst only. 22162306a36Sopenharmony_ci */ 22262306a36Sopenharmony_ci src = req->src; 22362306a36Sopenharmony_ci dst = req->dst; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 22662306a36Sopenharmony_ci struct scatter_walk src_walk, dst_walk; 22762306a36Sopenharmony_ci unsigned int nbytes = req->cryptlen; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci scatterwalk_start(&src_walk, src); 23062306a36Sopenharmony_ci scatterwalk_start(&dst_walk, dst); 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci while (nbytes) { 23362306a36Sopenharmony_ci /* get the source block */ 23462306a36Sopenharmony_ci scatterwalk_copychunks(&block.R, &src_walk, SEMIBSIZE, 23562306a36Sopenharmony_ci false); 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci /* perform KW operation: encrypt block */ 23862306a36Sopenharmony_ci crypto_cipher_encrypt_one(cipher, (u8 *)&block, 23962306a36Sopenharmony_ci (u8 *)&block); 24062306a36Sopenharmony_ci /* perform KW operation: modify IV with counter */ 24162306a36Sopenharmony_ci block.A ^= cpu_to_be64(t); 24262306a36Sopenharmony_ci t++; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci /* Copy block->R into place */ 24562306a36Sopenharmony_ci scatterwalk_copychunks(&block.R, &dst_walk, SEMIBSIZE, 24662306a36Sopenharmony_ci true); 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci nbytes -= SEMIBSIZE; 24962306a36Sopenharmony_ci } 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci /* we now start to operate on the dst SGL only */ 25262306a36Sopenharmony_ci src = req->dst; 25362306a36Sopenharmony_ci dst = req->dst; 25462306a36Sopenharmony_ci } 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci /* establish the IV for the caller to pick up */ 25762306a36Sopenharmony_ci memcpy(req->iv, &block.A, SEMIBSIZE); 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci memzero_explicit(&block, sizeof(struct crypto_kw_block)); 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci return 0; 26262306a36Sopenharmony_ci} 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_cistatic int crypto_kw_create(struct crypto_template *tmpl, struct rtattr **tb) 26562306a36Sopenharmony_ci{ 26662306a36Sopenharmony_ci struct skcipher_instance *inst; 26762306a36Sopenharmony_ci struct crypto_alg *alg; 26862306a36Sopenharmony_ci int err; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci inst = skcipher_alloc_instance_simple(tmpl, tb); 27162306a36Sopenharmony_ci if (IS_ERR(inst)) 27262306a36Sopenharmony_ci return PTR_ERR(inst); 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci alg = skcipher_ialg_simple(inst); 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci err = -EINVAL; 27762306a36Sopenharmony_ci /* Section 5.1 requirement for KW */ 27862306a36Sopenharmony_ci if (alg->cra_blocksize != sizeof(struct crypto_kw_block)) 27962306a36Sopenharmony_ci goto out_free_inst; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci inst->alg.base.cra_blocksize = SEMIBSIZE; 28262306a36Sopenharmony_ci inst->alg.base.cra_alignmask = 0; 28362306a36Sopenharmony_ci inst->alg.ivsize = SEMIBSIZE; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci inst->alg.encrypt = crypto_kw_encrypt; 28662306a36Sopenharmony_ci inst->alg.decrypt = crypto_kw_decrypt; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci err = skcipher_register_instance(tmpl, inst); 28962306a36Sopenharmony_ci if (err) { 29062306a36Sopenharmony_ciout_free_inst: 29162306a36Sopenharmony_ci inst->free(inst); 29262306a36Sopenharmony_ci } 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci return err; 29562306a36Sopenharmony_ci} 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_cistatic struct crypto_template crypto_kw_tmpl = { 29862306a36Sopenharmony_ci .name = "kw", 29962306a36Sopenharmony_ci .create = crypto_kw_create, 30062306a36Sopenharmony_ci .module = THIS_MODULE, 30162306a36Sopenharmony_ci}; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_cistatic int __init crypto_kw_init(void) 30462306a36Sopenharmony_ci{ 30562306a36Sopenharmony_ci return crypto_register_template(&crypto_kw_tmpl); 30662306a36Sopenharmony_ci} 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_cistatic void __exit crypto_kw_exit(void) 30962306a36Sopenharmony_ci{ 31062306a36Sopenharmony_ci crypto_unregister_template(&crypto_kw_tmpl); 31162306a36Sopenharmony_ci} 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_cisubsys_initcall(crypto_kw_init); 31462306a36Sopenharmony_cimodule_exit(crypto_kw_exit); 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 31762306a36Sopenharmony_ciMODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>"); 31862306a36Sopenharmony_ciMODULE_DESCRIPTION("Key Wrapping (RFC3394 / NIST SP800-38F)"); 31962306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("kw"); 32062306a36Sopenharmony_ciMODULE_IMPORT_NS(CRYPTO_INTERNAL); 321