/* * Key Wrapping: RFC3394 / NIST SP800-38F * * Copyright (C) 2015, Stephan Mueller <[email protected]> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * ALTERNATIVELY, this product may be distributed under the terms of * the GNU General Public License, in which case the provisions of the GPL2 * are required INSTEAD OF the above restrictions. (This clause is * necessary due to a potential bad interaction between the GPL and * the restrictions contained in a BSD-style copyright.) * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ /* * Note for using key wrapping: * * * The result of the encryption operation is the ciphertext starting * with the 2nd semiblock. The first semiblock is provided as the IV. * The IV used to start the encryption operation is the default IV. * * * The input for the decryption is the first semiblock handed in as an * IV. The ciphertext is the data starting with the 2nd semiblock. The * return code of the decryption operation will be EBADMSG in case an * integrity error occurs. * * To obtain the full result of an encryption as expected by SP800-38F, the * caller must allocate a buffer of plaintext + 8 bytes: * * unsigned int datalen = ptlen + crypto_skcipher_ivsize(tfm); * u8 data[datalen]; * u8 *iv = data; * u8 *pt = data + crypto_skcipher_ivsize(tfm); * <ensure that pt contains the plaintext of size ptlen> * sg_init_one(&sg, pt, ptlen); * skcipher_request_set_crypt(req, &sg, &sg, ptlen, iv); * * ==> After encryption, data now contains full KW result as per SP800-38F. * * In case of decryption, ciphertext now already has the expected length * and must be segmented appropriately: * * unsigned int datalen = CTLEN; * u8 data[datalen]; * <ensure that data contains full ciphertext> * u8 *iv = data; * u8 *ct = data + crypto_skcipher_ivsize(tfm); * unsigned int ctlen = datalen - crypto_skcipher_ivsize(tfm); * sg_init_one(&sg, ct, ctlen); * skcipher_request_set_crypt(req, &sg, &sg, ctlen, iv); * * ==> After decryption (which hopefully does not return EBADMSG), the ct * pointer now points to the plaintext of size ctlen. * * Note 2: KWP is not implemented as this would defy in-place operation. * If somebody wants to wrap non-aligned data, he should simply pad * the input with zeros to fill it up to the 8 byte boundary. */ #include <linux/module.h> #include <linux/crypto.h> #include <linux/scatterlist.h> #include <crypto/scatterwalk.h> #include <crypto/internal/cipher.h> #include <crypto/internal/skcipher.h> struct crypto_kw_block { … }; /* * Fast forward the SGL to the "end" length minus SEMIBSIZE. * The start in the SGL defined by the fast-forward is returned with * the walk variable */ static void crypto_kw_scatterlist_ff(struct scatter_walk *walk, struct scatterlist *sg, unsigned int end) { … } static int crypto_kw_decrypt(struct skcipher_request *req) { … } static int crypto_kw_encrypt(struct skcipher_request *req) { … } static int crypto_kw_create(struct crypto_template *tmpl, struct rtattr **tb) { … } static struct crypto_template crypto_kw_tmpl = …; static int __init crypto_kw_init(void) { … } static void __exit crypto_kw_exit(void) { … } subsys_initcall(crypto_kw_init); module_exit(crypto_kw_exit); MODULE_LICENSE(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_ALIAS_CRYPTO(…) …; MODULE_IMPORT_NS(…);