Back to home page

LXR

 
 

    


0001 /* FCrypt encryption algorithm
0002  *
0003  * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
0004  * Written by David Howells (dhowells@redhat.com)
0005  *
0006  * This program is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU General Public License
0008  * as published by the Free Software Foundation; either version
0009  * 2 of the License, or (at your option) any later version.
0010  *
0011  * Based on code:
0012  *
0013  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
0014  * (Royal Institute of Technology, Stockholm, Sweden).
0015  * All rights reserved.
0016  *
0017  * Redistribution and use in source and binary forms, with or without
0018  * modification, are permitted provided that the following conditions
0019  * are met:
0020  *
0021  * 1. Redistributions of source code must retain the above copyright
0022  *    notice, this list of conditions and the following disclaimer.
0023  *
0024  * 2. Redistributions in binary form must reproduce the above copyright
0025  *    notice, this list of conditions and the following disclaimer in the
0026  *    documentation and/or other materials provided with the distribution.
0027  *
0028  * 3. Neither the name of the Institute nor the names of its contributors
0029  *    may be used to endorse or promote products derived from this software
0030  *    without specific prior written permission.
0031  *
0032  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
0033  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0034  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0035  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
0036  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0037  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0038  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0039  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0040  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0041  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0042  * SUCH DAMAGE.
0043  */
0044 
0045 #include <asm/byteorder.h>
0046 #include <linux/bitops.h>
0047 #include <linux/init.h>
0048 #include <linux/module.h>
0049 #include <linux/crypto.h>
0050 
0051 #define ROUNDS 16
0052 
0053 struct fcrypt_ctx {
0054     __be32 sched[ROUNDS];
0055 };
0056 
0057 /* Rotate right two 32 bit numbers as a 56 bit number */
0058 #define ror56(hi, lo, n)                    \
0059 do {                                \
0060     u32 t = lo & ((1 << n) - 1);                \
0061     lo = (lo >> n) | ((hi & ((1 << n) - 1)) << (32 - n));   \
0062     hi = (hi >> n) | (t << (24-n));             \
0063 } while (0)
0064 
0065 /* Rotate right one 64 bit number as a 56 bit number */
0066 #define ror56_64(k, n)                      \
0067 do {                                \
0068     k = (k >> n) | ((k & ((1 << n) - 1)) << (56 - n));  \
0069 } while (0)
0070 
0071 /*
0072  * Sboxes for Feistel network derived from
0073  * /afs/transarc.com/public/afsps/afs.rel31b.export-src/rxkad/sboxes.h
0074  */
0075 #undef Z
0076 #define Z(x) cpu_to_be32(x << 3)
0077 static const __be32 sbox0[256] = {
0078     Z(0xea), Z(0x7f), Z(0xb2), Z(0x64), Z(0x9d), Z(0xb0), Z(0xd9), Z(0x11),
0079     Z(0xcd), Z(0x86), Z(0x86), Z(0x91), Z(0x0a), Z(0xb2), Z(0x93), Z(0x06),
0080     Z(0x0e), Z(0x06), Z(0xd2), Z(0x65), Z(0x73), Z(0xc5), Z(0x28), Z(0x60),
0081     Z(0xf2), Z(0x20), Z(0xb5), Z(0x38), Z(0x7e), Z(0xda), Z(0x9f), Z(0xe3),
0082     Z(0xd2), Z(0xcf), Z(0xc4), Z(0x3c), Z(0x61), Z(0xff), Z(0x4a), Z(0x4a),
0083     Z(0x35), Z(0xac), Z(0xaa), Z(0x5f), Z(0x2b), Z(0xbb), Z(0xbc), Z(0x53),
0084     Z(0x4e), Z(0x9d), Z(0x78), Z(0xa3), Z(0xdc), Z(0x09), Z(0x32), Z(0x10),
0085     Z(0xc6), Z(0x6f), Z(0x66), Z(0xd6), Z(0xab), Z(0xa9), Z(0xaf), Z(0xfd),
0086     Z(0x3b), Z(0x95), Z(0xe8), Z(0x34), Z(0x9a), Z(0x81), Z(0x72), Z(0x80),
0087     Z(0x9c), Z(0xf3), Z(0xec), Z(0xda), Z(0x9f), Z(0x26), Z(0x76), Z(0x15),
0088     Z(0x3e), Z(0x55), Z(0x4d), Z(0xde), Z(0x84), Z(0xee), Z(0xad), Z(0xc7),
0089     Z(0xf1), Z(0x6b), Z(0x3d), Z(0xd3), Z(0x04), Z(0x49), Z(0xaa), Z(0x24),
0090     Z(0x0b), Z(0x8a), Z(0x83), Z(0xba), Z(0xfa), Z(0x85), Z(0xa0), Z(0xa8),
0091     Z(0xb1), Z(0xd4), Z(0x01), Z(0xd8), Z(0x70), Z(0x64), Z(0xf0), Z(0x51),
0092     Z(0xd2), Z(0xc3), Z(0xa7), Z(0x75), Z(0x8c), Z(0xa5), Z(0x64), Z(0xef),
0093     Z(0x10), Z(0x4e), Z(0xb7), Z(0xc6), Z(0x61), Z(0x03), Z(0xeb), Z(0x44),
0094     Z(0x3d), Z(0xe5), Z(0xb3), Z(0x5b), Z(0xae), Z(0xd5), Z(0xad), Z(0x1d),
0095     Z(0xfa), Z(0x5a), Z(0x1e), Z(0x33), Z(0xab), Z(0x93), Z(0xa2), Z(0xb7),
0096     Z(0xe7), Z(0xa8), Z(0x45), Z(0xa4), Z(0xcd), Z(0x29), Z(0x63), Z(0x44),
0097     Z(0xb6), Z(0x69), Z(0x7e), Z(0x2e), Z(0x62), Z(0x03), Z(0xc8), Z(0xe0),
0098     Z(0x17), Z(0xbb), Z(0xc7), Z(0xf3), Z(0x3f), Z(0x36), Z(0xba), Z(0x71),
0099     Z(0x8e), Z(0x97), Z(0x65), Z(0x60), Z(0x69), Z(0xb6), Z(0xf6), Z(0xe6),
0100     Z(0x6e), Z(0xe0), Z(0x81), Z(0x59), Z(0xe8), Z(0xaf), Z(0xdd), Z(0x95),
0101     Z(0x22), Z(0x99), Z(0xfd), Z(0x63), Z(0x19), Z(0x74), Z(0x61), Z(0xb1),
0102     Z(0xb6), Z(0x5b), Z(0xae), Z(0x54), Z(0xb3), Z(0x70), Z(0xff), Z(0xc6),
0103     Z(0x3b), Z(0x3e), Z(0xc1), Z(0xd7), Z(0xe1), Z(0x0e), Z(0x76), Z(0xe5),
0104     Z(0x36), Z(0x4f), Z(0x59), Z(0xc7), Z(0x08), Z(0x6e), Z(0x82), Z(0xa6),
0105     Z(0x93), Z(0xc4), Z(0xaa), Z(0x26), Z(0x49), Z(0xe0), Z(0x21), Z(0x64),
0106     Z(0x07), Z(0x9f), Z(0x64), Z(0x81), Z(0x9c), Z(0xbf), Z(0xf9), Z(0xd1),
0107     Z(0x43), Z(0xf8), Z(0xb6), Z(0xb9), Z(0xf1), Z(0x24), Z(0x75), Z(0x03),
0108     Z(0xe4), Z(0xb0), Z(0x99), Z(0x46), Z(0x3d), Z(0xf5), Z(0xd1), Z(0x39),
0109     Z(0x72), Z(0x12), Z(0xf6), Z(0xba), Z(0x0c), Z(0x0d), Z(0x42), Z(0x2e)
0110 };
0111 
0112 #undef Z
0113 #define Z(x) cpu_to_be32(((x & 0x1f) << 27) | (x >> 5))
0114 static const __be32 sbox1[256] = {
0115     Z(0x77), Z(0x14), Z(0xa6), Z(0xfe), Z(0xb2), Z(0x5e), Z(0x8c), Z(0x3e),
0116     Z(0x67), Z(0x6c), Z(0xa1), Z(0x0d), Z(0xc2), Z(0xa2), Z(0xc1), Z(0x85),
0117     Z(0x6c), Z(0x7b), Z(0x67), Z(0xc6), Z(0x23), Z(0xe3), Z(0xf2), Z(0x89),
0118     Z(0x50), Z(0x9c), Z(0x03), Z(0xb7), Z(0x73), Z(0xe6), Z(0xe1), Z(0x39),
0119     Z(0x31), Z(0x2c), Z(0x27), Z(0x9f), Z(0xa5), Z(0x69), Z(0x44), Z(0xd6),
0120     Z(0x23), Z(0x83), Z(0x98), Z(0x7d), Z(0x3c), Z(0xb4), Z(0x2d), Z(0x99),
0121     Z(0x1c), Z(0x1f), Z(0x8c), Z(0x20), Z(0x03), Z(0x7c), Z(0x5f), Z(0xad),
0122     Z(0xf4), Z(0xfa), Z(0x95), Z(0xca), Z(0x76), Z(0x44), Z(0xcd), Z(0xb6),
0123     Z(0xb8), Z(0xa1), Z(0xa1), Z(0xbe), Z(0x9e), Z(0x54), Z(0x8f), Z(0x0b),
0124     Z(0x16), Z(0x74), Z(0x31), Z(0x8a), Z(0x23), Z(0x17), Z(0x04), Z(0xfa),
0125     Z(0x79), Z(0x84), Z(0xb1), Z(0xf5), Z(0x13), Z(0xab), Z(0xb5), Z(0x2e),
0126     Z(0xaa), Z(0x0c), Z(0x60), Z(0x6b), Z(0x5b), Z(0xc4), Z(0x4b), Z(0xbc),
0127     Z(0xe2), Z(0xaf), Z(0x45), Z(0x73), Z(0xfa), Z(0xc9), Z(0x49), Z(0xcd),
0128     Z(0x00), Z(0x92), Z(0x7d), Z(0x97), Z(0x7a), Z(0x18), Z(0x60), Z(0x3d),
0129     Z(0xcf), Z(0x5b), Z(0xde), Z(0xc6), Z(0xe2), Z(0xe6), Z(0xbb), Z(0x8b),
0130     Z(0x06), Z(0xda), Z(0x08), Z(0x15), Z(0x1b), Z(0x88), Z(0x6a), Z(0x17),
0131     Z(0x89), Z(0xd0), Z(0xa9), Z(0xc1), Z(0xc9), Z(0x70), Z(0x6b), Z(0xe5),
0132     Z(0x43), Z(0xf4), Z(0x68), Z(0xc8), Z(0xd3), Z(0x84), Z(0x28), Z(0x0a),
0133     Z(0x52), Z(0x66), Z(0xa3), Z(0xca), Z(0xf2), Z(0xe3), Z(0x7f), Z(0x7a),
0134     Z(0x31), Z(0xf7), Z(0x88), Z(0x94), Z(0x5e), Z(0x9c), Z(0x63), Z(0xd5),
0135     Z(0x24), Z(0x66), Z(0xfc), Z(0xb3), Z(0x57), Z(0x25), Z(0xbe), Z(0x89),
0136     Z(0x44), Z(0xc4), Z(0xe0), Z(0x8f), Z(0x23), Z(0x3c), Z(0x12), Z(0x52),
0137     Z(0xf5), Z(0x1e), Z(0xf4), Z(0xcb), Z(0x18), Z(0x33), Z(0x1f), Z(0xf8),
0138     Z(0x69), Z(0x10), Z(0x9d), Z(0xd3), Z(0xf7), Z(0x28), Z(0xf8), Z(0x30),
0139     Z(0x05), Z(0x5e), Z(0x32), Z(0xc0), Z(0xd5), Z(0x19), Z(0xbd), Z(0x45),
0140     Z(0x8b), Z(0x5b), Z(0xfd), Z(0xbc), Z(0xe2), Z(0x5c), Z(0xa9), Z(0x96),
0141     Z(0xef), Z(0x70), Z(0xcf), Z(0xc2), Z(0x2a), Z(0xb3), Z(0x61), Z(0xad),
0142     Z(0x80), Z(0x48), Z(0x81), Z(0xb7), Z(0x1d), Z(0x43), Z(0xd9), Z(0xd7),
0143     Z(0x45), Z(0xf0), Z(0xd8), Z(0x8a), Z(0x59), Z(0x7c), Z(0x57), Z(0xc1),
0144     Z(0x79), Z(0xc7), Z(0x34), Z(0xd6), Z(0x43), Z(0xdf), Z(0xe4), Z(0x78),
0145     Z(0x16), Z(0x06), Z(0xda), Z(0x92), Z(0x76), Z(0x51), Z(0xe1), Z(0xd4),
0146     Z(0x70), Z(0x03), Z(0xe0), Z(0x2f), Z(0x96), Z(0x91), Z(0x82), Z(0x80)
0147 };
0148 
0149 #undef Z
0150 #define Z(x) cpu_to_be32(x << 11)
0151 static const __be32 sbox2[256] = {
0152     Z(0xf0), Z(0x37), Z(0x24), Z(0x53), Z(0x2a), Z(0x03), Z(0x83), Z(0x86),
0153     Z(0xd1), Z(0xec), Z(0x50), Z(0xf0), Z(0x42), Z(0x78), Z(0x2f), Z(0x6d),
0154     Z(0xbf), Z(0x80), Z(0x87), Z(0x27), Z(0x95), Z(0xe2), Z(0xc5), Z(0x5d),
0155     Z(0xf9), Z(0x6f), Z(0xdb), Z(0xb4), Z(0x65), Z(0x6e), Z(0xe7), Z(0x24),
0156     Z(0xc8), Z(0x1a), Z(0xbb), Z(0x49), Z(0xb5), Z(0x0a), Z(0x7d), Z(0xb9),
0157     Z(0xe8), Z(0xdc), Z(0xb7), Z(0xd9), Z(0x45), Z(0x20), Z(0x1b), Z(0xce),
0158     Z(0x59), Z(0x9d), Z(0x6b), Z(0xbd), Z(0x0e), Z(0x8f), Z(0xa3), Z(0xa9),
0159     Z(0xbc), Z(0x74), Z(0xa6), Z(0xf6), Z(0x7f), Z(0x5f), Z(0xb1), Z(0x68),
0160     Z(0x84), Z(0xbc), Z(0xa9), Z(0xfd), Z(0x55), Z(0x50), Z(0xe9), Z(0xb6),
0161     Z(0x13), Z(0x5e), Z(0x07), Z(0xb8), Z(0x95), Z(0x02), Z(0xc0), Z(0xd0),
0162     Z(0x6a), Z(0x1a), Z(0x85), Z(0xbd), Z(0xb6), Z(0xfd), Z(0xfe), Z(0x17),
0163     Z(0x3f), Z(0x09), Z(0xa3), Z(0x8d), Z(0xfb), Z(0xed), Z(0xda), Z(0x1d),
0164     Z(0x6d), Z(0x1c), Z(0x6c), Z(0x01), Z(0x5a), Z(0xe5), Z(0x71), Z(0x3e),
0165     Z(0x8b), Z(0x6b), Z(0xbe), Z(0x29), Z(0xeb), Z(0x12), Z(0x19), Z(0x34),
0166     Z(0xcd), Z(0xb3), Z(0xbd), Z(0x35), Z(0xea), Z(0x4b), Z(0xd5), Z(0xae),
0167     Z(0x2a), Z(0x79), Z(0x5a), Z(0xa5), Z(0x32), Z(0x12), Z(0x7b), Z(0xdc),
0168     Z(0x2c), Z(0xd0), Z(0x22), Z(0x4b), Z(0xb1), Z(0x85), Z(0x59), Z(0x80),
0169     Z(0xc0), Z(0x30), Z(0x9f), Z(0x73), Z(0xd3), Z(0x14), Z(0x48), Z(0x40),
0170     Z(0x07), Z(0x2d), Z(0x8f), Z(0x80), Z(0x0f), Z(0xce), Z(0x0b), Z(0x5e),
0171     Z(0xb7), Z(0x5e), Z(0xac), Z(0x24), Z(0x94), Z(0x4a), Z(0x18), Z(0x15),
0172     Z(0x05), Z(0xe8), Z(0x02), Z(0x77), Z(0xa9), Z(0xc7), Z(0x40), Z(0x45),
0173     Z(0x89), Z(0xd1), Z(0xea), Z(0xde), Z(0x0c), Z(0x79), Z(0x2a), Z(0x99),
0174     Z(0x6c), Z(0x3e), Z(0x95), Z(0xdd), Z(0x8c), Z(0x7d), Z(0xad), Z(0x6f),
0175     Z(0xdc), Z(0xff), Z(0xfd), Z(0x62), Z(0x47), Z(0xb3), Z(0x21), Z(0x8a),
0176     Z(0xec), Z(0x8e), Z(0x19), Z(0x18), Z(0xb4), Z(0x6e), Z(0x3d), Z(0xfd),
0177     Z(0x74), Z(0x54), Z(0x1e), Z(0x04), Z(0x85), Z(0xd8), Z(0xbc), Z(0x1f),
0178     Z(0x56), Z(0xe7), Z(0x3a), Z(0x56), Z(0x67), Z(0xd6), Z(0xc8), Z(0xa5),
0179     Z(0xf3), Z(0x8e), Z(0xde), Z(0xae), Z(0x37), Z(0x49), Z(0xb7), Z(0xfa),
0180     Z(0xc8), Z(0xf4), Z(0x1f), Z(0xe0), Z(0x2a), Z(0x9b), Z(0x15), Z(0xd1),
0181     Z(0x34), Z(0x0e), Z(0xb5), Z(0xe0), Z(0x44), Z(0x78), Z(0x84), Z(0x59),
0182     Z(0x56), Z(0x68), Z(0x77), Z(0xa5), Z(0x14), Z(0x06), Z(0xf5), Z(0x2f),
0183     Z(0x8c), Z(0x8a), Z(0x73), Z(0x80), Z(0x76), Z(0xb4), Z(0x10), Z(0x86)
0184 };
0185 
0186 #undef Z
0187 #define Z(x) cpu_to_be32(x << 19)
0188 static const __be32 sbox3[256] = {
0189     Z(0xa9), Z(0x2a), Z(0x48), Z(0x51), Z(0x84), Z(0x7e), Z(0x49), Z(0xe2),
0190     Z(0xb5), Z(0xb7), Z(0x42), Z(0x33), Z(0x7d), Z(0x5d), Z(0xa6), Z(0x12),
0191     Z(0x44), Z(0x48), Z(0x6d), Z(0x28), Z(0xaa), Z(0x20), Z(0x6d), Z(0x57),
0192     Z(0xd6), Z(0x6b), Z(0x5d), Z(0x72), Z(0xf0), Z(0x92), Z(0x5a), Z(0x1b),
0193     Z(0x53), Z(0x80), Z(0x24), Z(0x70), Z(0x9a), Z(0xcc), Z(0xa7), Z(0x66),
0194     Z(0xa1), Z(0x01), Z(0xa5), Z(0x41), Z(0x97), Z(0x41), Z(0x31), Z(0x82),
0195     Z(0xf1), Z(0x14), Z(0xcf), Z(0x53), Z(0x0d), Z(0xa0), Z(0x10), Z(0xcc),
0196     Z(0x2a), Z(0x7d), Z(0xd2), Z(0xbf), Z(0x4b), Z(0x1a), Z(0xdb), Z(0x16),
0197     Z(0x47), Z(0xf6), Z(0x51), Z(0x36), Z(0xed), Z(0xf3), Z(0xb9), Z(0x1a),
0198     Z(0xa7), Z(0xdf), Z(0x29), Z(0x43), Z(0x01), Z(0x54), Z(0x70), Z(0xa4),
0199     Z(0xbf), Z(0xd4), Z(0x0b), Z(0x53), Z(0x44), Z(0x60), Z(0x9e), Z(0x23),
0200     Z(0xa1), Z(0x18), Z(0x68), Z(0x4f), Z(0xf0), Z(0x2f), Z(0x82), Z(0xc2),
0201     Z(0x2a), Z(0x41), Z(0xb2), Z(0x42), Z(0x0c), Z(0xed), Z(0x0c), Z(0x1d),
0202     Z(0x13), Z(0x3a), Z(0x3c), Z(0x6e), Z(0x35), Z(0xdc), Z(0x60), Z(0x65),
0203     Z(0x85), Z(0xe9), Z(0x64), Z(0x02), Z(0x9a), Z(0x3f), Z(0x9f), Z(0x87),
0204     Z(0x96), Z(0xdf), Z(0xbe), Z(0xf2), Z(0xcb), Z(0xe5), Z(0x6c), Z(0xd4),
0205     Z(0x5a), Z(0x83), Z(0xbf), Z(0x92), Z(0x1b), Z(0x94), Z(0x00), Z(0x42),
0206     Z(0xcf), Z(0x4b), Z(0x00), Z(0x75), Z(0xba), Z(0x8f), Z(0x76), Z(0x5f),
0207     Z(0x5d), Z(0x3a), Z(0x4d), Z(0x09), Z(0x12), Z(0x08), Z(0x38), Z(0x95),
0208     Z(0x17), Z(0xe4), Z(0x01), Z(0x1d), Z(0x4c), Z(0xa9), Z(0xcc), Z(0x85),
0209     Z(0x82), Z(0x4c), Z(0x9d), Z(0x2f), Z(0x3b), Z(0x66), Z(0xa1), Z(0x34),
0210     Z(0x10), Z(0xcd), Z(0x59), Z(0x89), Z(0xa5), Z(0x31), Z(0xcf), Z(0x05),
0211     Z(0xc8), Z(0x84), Z(0xfa), Z(0xc7), Z(0xba), Z(0x4e), Z(0x8b), Z(0x1a),
0212     Z(0x19), Z(0xf1), Z(0xa1), Z(0x3b), Z(0x18), Z(0x12), Z(0x17), Z(0xb0),
0213     Z(0x98), Z(0x8d), Z(0x0b), Z(0x23), Z(0xc3), Z(0x3a), Z(0x2d), Z(0x20),
0214     Z(0xdf), Z(0x13), Z(0xa0), Z(0xa8), Z(0x4c), Z(0x0d), Z(0x6c), Z(0x2f),
0215     Z(0x47), Z(0x13), Z(0x13), Z(0x52), Z(0x1f), Z(0x2d), Z(0xf5), Z(0x79),
0216     Z(0x3d), Z(0xa2), Z(0x54), Z(0xbd), Z(0x69), Z(0xc8), Z(0x6b), Z(0xf3),
0217     Z(0x05), Z(0x28), Z(0xf1), Z(0x16), Z(0x46), Z(0x40), Z(0xb0), Z(0x11),
0218     Z(0xd3), Z(0xb7), Z(0x95), Z(0x49), Z(0xcf), Z(0xc3), Z(0x1d), Z(0x8f),
0219     Z(0xd8), Z(0xe1), Z(0x73), Z(0xdb), Z(0xad), Z(0xc8), Z(0xc9), Z(0xa9),
0220     Z(0xa1), Z(0xc2), Z(0xc5), Z(0xe3), Z(0xba), Z(0xfc), Z(0x0e), Z(0x25)
0221 };
0222 
0223 /*
0224  * This is a 16 round Feistel network with permutation F_ENCRYPT
0225  */
0226 #define F_ENCRYPT(R, L, sched)                      \
0227 do {                                    \
0228     union lc4 { __be32 l; u8 c[4]; } u;             \
0229     u.l = sched ^ R;                        \
0230     L ^= sbox0[u.c[0]] ^ sbox1[u.c[1]] ^ sbox2[u.c[2]] ^ sbox3[u.c[3]]; \
0231 } while (0)
0232 
0233 /*
0234  * encryptor
0235  */
0236 static void fcrypt_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0237 {
0238     const struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm);
0239     struct {
0240         __be32 l, r;
0241     } X;
0242 
0243     memcpy(&X, src, sizeof(X));
0244 
0245     F_ENCRYPT(X.r, X.l, ctx->sched[0x0]);
0246     F_ENCRYPT(X.l, X.r, ctx->sched[0x1]);
0247     F_ENCRYPT(X.r, X.l, ctx->sched[0x2]);
0248     F_ENCRYPT(X.l, X.r, ctx->sched[0x3]);
0249     F_ENCRYPT(X.r, X.l, ctx->sched[0x4]);
0250     F_ENCRYPT(X.l, X.r, ctx->sched[0x5]);
0251     F_ENCRYPT(X.r, X.l, ctx->sched[0x6]);
0252     F_ENCRYPT(X.l, X.r, ctx->sched[0x7]);
0253     F_ENCRYPT(X.r, X.l, ctx->sched[0x8]);
0254     F_ENCRYPT(X.l, X.r, ctx->sched[0x9]);
0255     F_ENCRYPT(X.r, X.l, ctx->sched[0xa]);
0256     F_ENCRYPT(X.l, X.r, ctx->sched[0xb]);
0257     F_ENCRYPT(X.r, X.l, ctx->sched[0xc]);
0258     F_ENCRYPT(X.l, X.r, ctx->sched[0xd]);
0259     F_ENCRYPT(X.r, X.l, ctx->sched[0xe]);
0260     F_ENCRYPT(X.l, X.r, ctx->sched[0xf]);
0261 
0262     memcpy(dst, &X, sizeof(X));
0263 }
0264 
0265 /*
0266  * decryptor
0267  */
0268 static void fcrypt_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0269 {
0270     const struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm);
0271     struct {
0272         __be32 l, r;
0273     } X;
0274 
0275     memcpy(&X, src, sizeof(X));
0276 
0277     F_ENCRYPT(X.l, X.r, ctx->sched[0xf]);
0278     F_ENCRYPT(X.r, X.l, ctx->sched[0xe]);
0279     F_ENCRYPT(X.l, X.r, ctx->sched[0xd]);
0280     F_ENCRYPT(X.r, X.l, ctx->sched[0xc]);
0281     F_ENCRYPT(X.l, X.r, ctx->sched[0xb]);
0282     F_ENCRYPT(X.r, X.l, ctx->sched[0xa]);
0283     F_ENCRYPT(X.l, X.r, ctx->sched[0x9]);
0284     F_ENCRYPT(X.r, X.l, ctx->sched[0x8]);
0285     F_ENCRYPT(X.l, X.r, ctx->sched[0x7]);
0286     F_ENCRYPT(X.r, X.l, ctx->sched[0x6]);
0287     F_ENCRYPT(X.l, X.r, ctx->sched[0x5]);
0288     F_ENCRYPT(X.r, X.l, ctx->sched[0x4]);
0289     F_ENCRYPT(X.l, X.r, ctx->sched[0x3]);
0290     F_ENCRYPT(X.r, X.l, ctx->sched[0x2]);
0291     F_ENCRYPT(X.l, X.r, ctx->sched[0x1]);
0292     F_ENCRYPT(X.r, X.l, ctx->sched[0x0]);
0293 
0294     memcpy(dst, &X, sizeof(X));
0295 }
0296 
0297 /*
0298  * Generate a key schedule from key, the least significant bit in each key byte
0299  * is parity and shall be ignored. This leaves 56 significant bits in the key
0300  * to scatter over the 16 key schedules. For each schedule extract the low
0301  * order 32 bits and use as schedule, then rotate right by 11 bits.
0302  */
0303 static int fcrypt_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
0304 {
0305     struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm);
0306 
0307 #if BITS_PER_LONG == 64  /* the 64-bit version can also be used for 32-bit
0308               * kernels - it seems to be faster but the code is
0309               * larger */
0310 
0311     u64 k;  /* k holds all 56 non-parity bits */
0312 
0313     /* discard the parity bits */
0314     k = (*key++) >> 1;
0315     k <<= 7;
0316     k |= (*key++) >> 1;
0317     k <<= 7;
0318     k |= (*key++) >> 1;
0319     k <<= 7;
0320     k |= (*key++) >> 1;
0321     k <<= 7;
0322     k |= (*key++) >> 1;
0323     k <<= 7;
0324     k |= (*key++) >> 1;
0325     k <<= 7;
0326     k |= (*key++) >> 1;
0327     k <<= 7;
0328     k |= (*key) >> 1;
0329 
0330     /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
0331     ctx->sched[0x0] = cpu_to_be32(k); ror56_64(k, 11);
0332     ctx->sched[0x1] = cpu_to_be32(k); ror56_64(k, 11);
0333     ctx->sched[0x2] = cpu_to_be32(k); ror56_64(k, 11);
0334     ctx->sched[0x3] = cpu_to_be32(k); ror56_64(k, 11);
0335     ctx->sched[0x4] = cpu_to_be32(k); ror56_64(k, 11);
0336     ctx->sched[0x5] = cpu_to_be32(k); ror56_64(k, 11);
0337     ctx->sched[0x6] = cpu_to_be32(k); ror56_64(k, 11);
0338     ctx->sched[0x7] = cpu_to_be32(k); ror56_64(k, 11);
0339     ctx->sched[0x8] = cpu_to_be32(k); ror56_64(k, 11);
0340     ctx->sched[0x9] = cpu_to_be32(k); ror56_64(k, 11);
0341     ctx->sched[0xa] = cpu_to_be32(k); ror56_64(k, 11);
0342     ctx->sched[0xb] = cpu_to_be32(k); ror56_64(k, 11);
0343     ctx->sched[0xc] = cpu_to_be32(k); ror56_64(k, 11);
0344     ctx->sched[0xd] = cpu_to_be32(k); ror56_64(k, 11);
0345     ctx->sched[0xe] = cpu_to_be32(k); ror56_64(k, 11);
0346     ctx->sched[0xf] = cpu_to_be32(k);
0347 
0348     return 0;
0349 #else
0350     u32 hi, lo;     /* hi is upper 24 bits and lo lower 32, total 56 */
0351 
0352     /* discard the parity bits */
0353     lo = (*key++) >> 1;
0354     lo <<= 7;
0355     lo |= (*key++) >> 1;
0356     lo <<= 7;
0357     lo |= (*key++) >> 1;
0358     lo <<= 7;
0359     lo |= (*key++) >> 1;
0360     hi = lo >> 4;
0361     lo &= 0xf;
0362     lo <<= 7;
0363     lo |= (*key++) >> 1;
0364     lo <<= 7;
0365     lo |= (*key++) >> 1;
0366     lo <<= 7;
0367     lo |= (*key++) >> 1;
0368     lo <<= 7;
0369     lo |= (*key) >> 1;
0370 
0371     /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
0372     ctx->sched[0x0] = cpu_to_be32(lo); ror56(hi, lo, 11);
0373     ctx->sched[0x1] = cpu_to_be32(lo); ror56(hi, lo, 11);
0374     ctx->sched[0x2] = cpu_to_be32(lo); ror56(hi, lo, 11);
0375     ctx->sched[0x3] = cpu_to_be32(lo); ror56(hi, lo, 11);
0376     ctx->sched[0x4] = cpu_to_be32(lo); ror56(hi, lo, 11);
0377     ctx->sched[0x5] = cpu_to_be32(lo); ror56(hi, lo, 11);
0378     ctx->sched[0x6] = cpu_to_be32(lo); ror56(hi, lo, 11);
0379     ctx->sched[0x7] = cpu_to_be32(lo); ror56(hi, lo, 11);
0380     ctx->sched[0x8] = cpu_to_be32(lo); ror56(hi, lo, 11);
0381     ctx->sched[0x9] = cpu_to_be32(lo); ror56(hi, lo, 11);
0382     ctx->sched[0xa] = cpu_to_be32(lo); ror56(hi, lo, 11);
0383     ctx->sched[0xb] = cpu_to_be32(lo); ror56(hi, lo, 11);
0384     ctx->sched[0xc] = cpu_to_be32(lo); ror56(hi, lo, 11);
0385     ctx->sched[0xd] = cpu_to_be32(lo); ror56(hi, lo, 11);
0386     ctx->sched[0xe] = cpu_to_be32(lo); ror56(hi, lo, 11);
0387     ctx->sched[0xf] = cpu_to_be32(lo);
0388     return 0;
0389 #endif
0390 }
0391 
0392 static struct crypto_alg fcrypt_alg = {
0393     .cra_name       =   "fcrypt",
0394     .cra_flags      =   CRYPTO_ALG_TYPE_CIPHER,
0395     .cra_blocksize      =   8,
0396     .cra_ctxsize        =   sizeof(struct fcrypt_ctx),
0397     .cra_module     =   THIS_MODULE,
0398     .cra_alignmask      =   3,
0399     .cra_u          =   { .cipher = {
0400     .cia_min_keysize    =   8,
0401     .cia_max_keysize    =   8,
0402     .cia_setkey     =   fcrypt_setkey,
0403     .cia_encrypt        =   fcrypt_encrypt,
0404     .cia_decrypt        =   fcrypt_decrypt } }
0405 };
0406 
0407 static int __init fcrypt_mod_init(void)
0408 {
0409     return crypto_register_alg(&fcrypt_alg);
0410 }
0411 
0412 static void __exit fcrypt_mod_fini(void)
0413 {
0414     crypto_unregister_alg(&fcrypt_alg);
0415 }
0416 
0417 module_init(fcrypt_mod_init);
0418 module_exit(fcrypt_mod_fini);
0419 
0420 MODULE_LICENSE("Dual BSD/GPL");
0421 MODULE_DESCRIPTION("FCrypt Cipher Algorithm");
0422 MODULE_AUTHOR("David Howells <dhowells@redhat.com>");
0423 MODULE_ALIAS_CRYPTO("fcrypt");