Back to home page

OSCL-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) (k = (k >> n) | ((k & ((1 << n) - 1)) << (56 - n)))
0067 
0068 /*
0069  * Sboxes for Feistel network derived from
0070  * /afs/transarc.com/public/afsps/afs.rel31b.export-src/rxkad/sboxes.h
0071  */
0072 #undef Z
0073 #define Z(x) cpu_to_be32(x << 3)
0074 static const __be32 sbox0[256] = {
0075     Z(0xea), Z(0x7f), Z(0xb2), Z(0x64), Z(0x9d), Z(0xb0), Z(0xd9), Z(0x11),
0076     Z(0xcd), Z(0x86), Z(0x86), Z(0x91), Z(0x0a), Z(0xb2), Z(0x93), Z(0x06),
0077     Z(0x0e), Z(0x06), Z(0xd2), Z(0x65), Z(0x73), Z(0xc5), Z(0x28), Z(0x60),
0078     Z(0xf2), Z(0x20), Z(0xb5), Z(0x38), Z(0x7e), Z(0xda), Z(0x9f), Z(0xe3),
0079     Z(0xd2), Z(0xcf), Z(0xc4), Z(0x3c), Z(0x61), Z(0xff), Z(0x4a), Z(0x4a),
0080     Z(0x35), Z(0xac), Z(0xaa), Z(0x5f), Z(0x2b), Z(0xbb), Z(0xbc), Z(0x53),
0081     Z(0x4e), Z(0x9d), Z(0x78), Z(0xa3), Z(0xdc), Z(0x09), Z(0x32), Z(0x10),
0082     Z(0xc6), Z(0x6f), Z(0x66), Z(0xd6), Z(0xab), Z(0xa9), Z(0xaf), Z(0xfd),
0083     Z(0x3b), Z(0x95), Z(0xe8), Z(0x34), Z(0x9a), Z(0x81), Z(0x72), Z(0x80),
0084     Z(0x9c), Z(0xf3), Z(0xec), Z(0xda), Z(0x9f), Z(0x26), Z(0x76), Z(0x15),
0085     Z(0x3e), Z(0x55), Z(0x4d), Z(0xde), Z(0x84), Z(0xee), Z(0xad), Z(0xc7),
0086     Z(0xf1), Z(0x6b), Z(0x3d), Z(0xd3), Z(0x04), Z(0x49), Z(0xaa), Z(0x24),
0087     Z(0x0b), Z(0x8a), Z(0x83), Z(0xba), Z(0xfa), Z(0x85), Z(0xa0), Z(0xa8),
0088     Z(0xb1), Z(0xd4), Z(0x01), Z(0xd8), Z(0x70), Z(0x64), Z(0xf0), Z(0x51),
0089     Z(0xd2), Z(0xc3), Z(0xa7), Z(0x75), Z(0x8c), Z(0xa5), Z(0x64), Z(0xef),
0090     Z(0x10), Z(0x4e), Z(0xb7), Z(0xc6), Z(0x61), Z(0x03), Z(0xeb), Z(0x44),
0091     Z(0x3d), Z(0xe5), Z(0xb3), Z(0x5b), Z(0xae), Z(0xd5), Z(0xad), Z(0x1d),
0092     Z(0xfa), Z(0x5a), Z(0x1e), Z(0x33), Z(0xab), Z(0x93), Z(0xa2), Z(0xb7),
0093     Z(0xe7), Z(0xa8), Z(0x45), Z(0xa4), Z(0xcd), Z(0x29), Z(0x63), Z(0x44),
0094     Z(0xb6), Z(0x69), Z(0x7e), Z(0x2e), Z(0x62), Z(0x03), Z(0xc8), Z(0xe0),
0095     Z(0x17), Z(0xbb), Z(0xc7), Z(0xf3), Z(0x3f), Z(0x36), Z(0xba), Z(0x71),
0096     Z(0x8e), Z(0x97), Z(0x65), Z(0x60), Z(0x69), Z(0xb6), Z(0xf6), Z(0xe6),
0097     Z(0x6e), Z(0xe0), Z(0x81), Z(0x59), Z(0xe8), Z(0xaf), Z(0xdd), Z(0x95),
0098     Z(0x22), Z(0x99), Z(0xfd), Z(0x63), Z(0x19), Z(0x74), Z(0x61), Z(0xb1),
0099     Z(0xb6), Z(0x5b), Z(0xae), Z(0x54), Z(0xb3), Z(0x70), Z(0xff), Z(0xc6),
0100     Z(0x3b), Z(0x3e), Z(0xc1), Z(0xd7), Z(0xe1), Z(0x0e), Z(0x76), Z(0xe5),
0101     Z(0x36), Z(0x4f), Z(0x59), Z(0xc7), Z(0x08), Z(0x6e), Z(0x82), Z(0xa6),
0102     Z(0x93), Z(0xc4), Z(0xaa), Z(0x26), Z(0x49), Z(0xe0), Z(0x21), Z(0x64),
0103     Z(0x07), Z(0x9f), Z(0x64), Z(0x81), Z(0x9c), Z(0xbf), Z(0xf9), Z(0xd1),
0104     Z(0x43), Z(0xf8), Z(0xb6), Z(0xb9), Z(0xf1), Z(0x24), Z(0x75), Z(0x03),
0105     Z(0xe4), Z(0xb0), Z(0x99), Z(0x46), Z(0x3d), Z(0xf5), Z(0xd1), Z(0x39),
0106     Z(0x72), Z(0x12), Z(0xf6), Z(0xba), Z(0x0c), Z(0x0d), Z(0x42), Z(0x2e)
0107 };
0108 
0109 #undef Z
0110 #define Z(x) cpu_to_be32(((x & 0x1f) << 27) | (x >> 5))
0111 static const __be32 sbox1[256] = {
0112     Z(0x77), Z(0x14), Z(0xa6), Z(0xfe), Z(0xb2), Z(0x5e), Z(0x8c), Z(0x3e),
0113     Z(0x67), Z(0x6c), Z(0xa1), Z(0x0d), Z(0xc2), Z(0xa2), Z(0xc1), Z(0x85),
0114     Z(0x6c), Z(0x7b), Z(0x67), Z(0xc6), Z(0x23), Z(0xe3), Z(0xf2), Z(0x89),
0115     Z(0x50), Z(0x9c), Z(0x03), Z(0xb7), Z(0x73), Z(0xe6), Z(0xe1), Z(0x39),
0116     Z(0x31), Z(0x2c), Z(0x27), Z(0x9f), Z(0xa5), Z(0x69), Z(0x44), Z(0xd6),
0117     Z(0x23), Z(0x83), Z(0x98), Z(0x7d), Z(0x3c), Z(0xb4), Z(0x2d), Z(0x99),
0118     Z(0x1c), Z(0x1f), Z(0x8c), Z(0x20), Z(0x03), Z(0x7c), Z(0x5f), Z(0xad),
0119     Z(0xf4), Z(0xfa), Z(0x95), Z(0xca), Z(0x76), Z(0x44), Z(0xcd), Z(0xb6),
0120     Z(0xb8), Z(0xa1), Z(0xa1), Z(0xbe), Z(0x9e), Z(0x54), Z(0x8f), Z(0x0b),
0121     Z(0x16), Z(0x74), Z(0x31), Z(0x8a), Z(0x23), Z(0x17), Z(0x04), Z(0xfa),
0122     Z(0x79), Z(0x84), Z(0xb1), Z(0xf5), Z(0x13), Z(0xab), Z(0xb5), Z(0x2e),
0123     Z(0xaa), Z(0x0c), Z(0x60), Z(0x6b), Z(0x5b), Z(0xc4), Z(0x4b), Z(0xbc),
0124     Z(0xe2), Z(0xaf), Z(0x45), Z(0x73), Z(0xfa), Z(0xc9), Z(0x49), Z(0xcd),
0125     Z(0x00), Z(0x92), Z(0x7d), Z(0x97), Z(0x7a), Z(0x18), Z(0x60), Z(0x3d),
0126     Z(0xcf), Z(0x5b), Z(0xde), Z(0xc6), Z(0xe2), Z(0xe6), Z(0xbb), Z(0x8b),
0127     Z(0x06), Z(0xda), Z(0x08), Z(0x15), Z(0x1b), Z(0x88), Z(0x6a), Z(0x17),
0128     Z(0x89), Z(0xd0), Z(0xa9), Z(0xc1), Z(0xc9), Z(0x70), Z(0x6b), Z(0xe5),
0129     Z(0x43), Z(0xf4), Z(0x68), Z(0xc8), Z(0xd3), Z(0x84), Z(0x28), Z(0x0a),
0130     Z(0x52), Z(0x66), Z(0xa3), Z(0xca), Z(0xf2), Z(0xe3), Z(0x7f), Z(0x7a),
0131     Z(0x31), Z(0xf7), Z(0x88), Z(0x94), Z(0x5e), Z(0x9c), Z(0x63), Z(0xd5),
0132     Z(0x24), Z(0x66), Z(0xfc), Z(0xb3), Z(0x57), Z(0x25), Z(0xbe), Z(0x89),
0133     Z(0x44), Z(0xc4), Z(0xe0), Z(0x8f), Z(0x23), Z(0x3c), Z(0x12), Z(0x52),
0134     Z(0xf5), Z(0x1e), Z(0xf4), Z(0xcb), Z(0x18), Z(0x33), Z(0x1f), Z(0xf8),
0135     Z(0x69), Z(0x10), Z(0x9d), Z(0xd3), Z(0xf7), Z(0x28), Z(0xf8), Z(0x30),
0136     Z(0x05), Z(0x5e), Z(0x32), Z(0xc0), Z(0xd5), Z(0x19), Z(0xbd), Z(0x45),
0137     Z(0x8b), Z(0x5b), Z(0xfd), Z(0xbc), Z(0xe2), Z(0x5c), Z(0xa9), Z(0x96),
0138     Z(0xef), Z(0x70), Z(0xcf), Z(0xc2), Z(0x2a), Z(0xb3), Z(0x61), Z(0xad),
0139     Z(0x80), Z(0x48), Z(0x81), Z(0xb7), Z(0x1d), Z(0x43), Z(0xd9), Z(0xd7),
0140     Z(0x45), Z(0xf0), Z(0xd8), Z(0x8a), Z(0x59), Z(0x7c), Z(0x57), Z(0xc1),
0141     Z(0x79), Z(0xc7), Z(0x34), Z(0xd6), Z(0x43), Z(0xdf), Z(0xe4), Z(0x78),
0142     Z(0x16), Z(0x06), Z(0xda), Z(0x92), Z(0x76), Z(0x51), Z(0xe1), Z(0xd4),
0143     Z(0x70), Z(0x03), Z(0xe0), Z(0x2f), Z(0x96), Z(0x91), Z(0x82), Z(0x80)
0144 };
0145 
0146 #undef Z
0147 #define Z(x) cpu_to_be32(x << 11)
0148 static const __be32 sbox2[256] = {
0149     Z(0xf0), Z(0x37), Z(0x24), Z(0x53), Z(0x2a), Z(0x03), Z(0x83), Z(0x86),
0150     Z(0xd1), Z(0xec), Z(0x50), Z(0xf0), Z(0x42), Z(0x78), Z(0x2f), Z(0x6d),
0151     Z(0xbf), Z(0x80), Z(0x87), Z(0x27), Z(0x95), Z(0xe2), Z(0xc5), Z(0x5d),
0152     Z(0xf9), Z(0x6f), Z(0xdb), Z(0xb4), Z(0x65), Z(0x6e), Z(0xe7), Z(0x24),
0153     Z(0xc8), Z(0x1a), Z(0xbb), Z(0x49), Z(0xb5), Z(0x0a), Z(0x7d), Z(0xb9),
0154     Z(0xe8), Z(0xdc), Z(0xb7), Z(0xd9), Z(0x45), Z(0x20), Z(0x1b), Z(0xce),
0155     Z(0x59), Z(0x9d), Z(0x6b), Z(0xbd), Z(0x0e), Z(0x8f), Z(0xa3), Z(0xa9),
0156     Z(0xbc), Z(0x74), Z(0xa6), Z(0xf6), Z(0x7f), Z(0x5f), Z(0xb1), Z(0x68),
0157     Z(0x84), Z(0xbc), Z(0xa9), Z(0xfd), Z(0x55), Z(0x50), Z(0xe9), Z(0xb6),
0158     Z(0x13), Z(0x5e), Z(0x07), Z(0xb8), Z(0x95), Z(0x02), Z(0xc0), Z(0xd0),
0159     Z(0x6a), Z(0x1a), Z(0x85), Z(0xbd), Z(0xb6), Z(0xfd), Z(0xfe), Z(0x17),
0160     Z(0x3f), Z(0x09), Z(0xa3), Z(0x8d), Z(0xfb), Z(0xed), Z(0xda), Z(0x1d),
0161     Z(0x6d), Z(0x1c), Z(0x6c), Z(0x01), Z(0x5a), Z(0xe5), Z(0x71), Z(0x3e),
0162     Z(0x8b), Z(0x6b), Z(0xbe), Z(0x29), Z(0xeb), Z(0x12), Z(0x19), Z(0x34),
0163     Z(0xcd), Z(0xb3), Z(0xbd), Z(0x35), Z(0xea), Z(0x4b), Z(0xd5), Z(0xae),
0164     Z(0x2a), Z(0x79), Z(0x5a), Z(0xa5), Z(0x32), Z(0x12), Z(0x7b), Z(0xdc),
0165     Z(0x2c), Z(0xd0), Z(0x22), Z(0x4b), Z(0xb1), Z(0x85), Z(0x59), Z(0x80),
0166     Z(0xc0), Z(0x30), Z(0x9f), Z(0x73), Z(0xd3), Z(0x14), Z(0x48), Z(0x40),
0167     Z(0x07), Z(0x2d), Z(0x8f), Z(0x80), Z(0x0f), Z(0xce), Z(0x0b), Z(0x5e),
0168     Z(0xb7), Z(0x5e), Z(0xac), Z(0x24), Z(0x94), Z(0x4a), Z(0x18), Z(0x15),
0169     Z(0x05), Z(0xe8), Z(0x02), Z(0x77), Z(0xa9), Z(0xc7), Z(0x40), Z(0x45),
0170     Z(0x89), Z(0xd1), Z(0xea), Z(0xde), Z(0x0c), Z(0x79), Z(0x2a), Z(0x99),
0171     Z(0x6c), Z(0x3e), Z(0x95), Z(0xdd), Z(0x8c), Z(0x7d), Z(0xad), Z(0x6f),
0172     Z(0xdc), Z(0xff), Z(0xfd), Z(0x62), Z(0x47), Z(0xb3), Z(0x21), Z(0x8a),
0173     Z(0xec), Z(0x8e), Z(0x19), Z(0x18), Z(0xb4), Z(0x6e), Z(0x3d), Z(0xfd),
0174     Z(0x74), Z(0x54), Z(0x1e), Z(0x04), Z(0x85), Z(0xd8), Z(0xbc), Z(0x1f),
0175     Z(0x56), Z(0xe7), Z(0x3a), Z(0x56), Z(0x67), Z(0xd6), Z(0xc8), Z(0xa5),
0176     Z(0xf3), Z(0x8e), Z(0xde), Z(0xae), Z(0x37), Z(0x49), Z(0xb7), Z(0xfa),
0177     Z(0xc8), Z(0xf4), Z(0x1f), Z(0xe0), Z(0x2a), Z(0x9b), Z(0x15), Z(0xd1),
0178     Z(0x34), Z(0x0e), Z(0xb5), Z(0xe0), Z(0x44), Z(0x78), Z(0x84), Z(0x59),
0179     Z(0x56), Z(0x68), Z(0x77), Z(0xa5), Z(0x14), Z(0x06), Z(0xf5), Z(0x2f),
0180     Z(0x8c), Z(0x8a), Z(0x73), Z(0x80), Z(0x76), Z(0xb4), Z(0x10), Z(0x86)
0181 };
0182 
0183 #undef Z
0184 #define Z(x) cpu_to_be32(x << 19)
0185 static const __be32 sbox3[256] = {
0186     Z(0xa9), Z(0x2a), Z(0x48), Z(0x51), Z(0x84), Z(0x7e), Z(0x49), Z(0xe2),
0187     Z(0xb5), Z(0xb7), Z(0x42), Z(0x33), Z(0x7d), Z(0x5d), Z(0xa6), Z(0x12),
0188     Z(0x44), Z(0x48), Z(0x6d), Z(0x28), Z(0xaa), Z(0x20), Z(0x6d), Z(0x57),
0189     Z(0xd6), Z(0x6b), Z(0x5d), Z(0x72), Z(0xf0), Z(0x92), Z(0x5a), Z(0x1b),
0190     Z(0x53), Z(0x80), Z(0x24), Z(0x70), Z(0x9a), Z(0xcc), Z(0xa7), Z(0x66),
0191     Z(0xa1), Z(0x01), Z(0xa5), Z(0x41), Z(0x97), Z(0x41), Z(0x31), Z(0x82),
0192     Z(0xf1), Z(0x14), Z(0xcf), Z(0x53), Z(0x0d), Z(0xa0), Z(0x10), Z(0xcc),
0193     Z(0x2a), Z(0x7d), Z(0xd2), Z(0xbf), Z(0x4b), Z(0x1a), Z(0xdb), Z(0x16),
0194     Z(0x47), Z(0xf6), Z(0x51), Z(0x36), Z(0xed), Z(0xf3), Z(0xb9), Z(0x1a),
0195     Z(0xa7), Z(0xdf), Z(0x29), Z(0x43), Z(0x01), Z(0x54), Z(0x70), Z(0xa4),
0196     Z(0xbf), Z(0xd4), Z(0x0b), Z(0x53), Z(0x44), Z(0x60), Z(0x9e), Z(0x23),
0197     Z(0xa1), Z(0x18), Z(0x68), Z(0x4f), Z(0xf0), Z(0x2f), Z(0x82), Z(0xc2),
0198     Z(0x2a), Z(0x41), Z(0xb2), Z(0x42), Z(0x0c), Z(0xed), Z(0x0c), Z(0x1d),
0199     Z(0x13), Z(0x3a), Z(0x3c), Z(0x6e), Z(0x35), Z(0xdc), Z(0x60), Z(0x65),
0200     Z(0x85), Z(0xe9), Z(0x64), Z(0x02), Z(0x9a), Z(0x3f), Z(0x9f), Z(0x87),
0201     Z(0x96), Z(0xdf), Z(0xbe), Z(0xf2), Z(0xcb), Z(0xe5), Z(0x6c), Z(0xd4),
0202     Z(0x5a), Z(0x83), Z(0xbf), Z(0x92), Z(0x1b), Z(0x94), Z(0x00), Z(0x42),
0203     Z(0xcf), Z(0x4b), Z(0x00), Z(0x75), Z(0xba), Z(0x8f), Z(0x76), Z(0x5f),
0204     Z(0x5d), Z(0x3a), Z(0x4d), Z(0x09), Z(0x12), Z(0x08), Z(0x38), Z(0x95),
0205     Z(0x17), Z(0xe4), Z(0x01), Z(0x1d), Z(0x4c), Z(0xa9), Z(0xcc), Z(0x85),
0206     Z(0x82), Z(0x4c), Z(0x9d), Z(0x2f), Z(0x3b), Z(0x66), Z(0xa1), Z(0x34),
0207     Z(0x10), Z(0xcd), Z(0x59), Z(0x89), Z(0xa5), Z(0x31), Z(0xcf), Z(0x05),
0208     Z(0xc8), Z(0x84), Z(0xfa), Z(0xc7), Z(0xba), Z(0x4e), Z(0x8b), Z(0x1a),
0209     Z(0x19), Z(0xf1), Z(0xa1), Z(0x3b), Z(0x18), Z(0x12), Z(0x17), Z(0xb0),
0210     Z(0x98), Z(0x8d), Z(0x0b), Z(0x23), Z(0xc3), Z(0x3a), Z(0x2d), Z(0x20),
0211     Z(0xdf), Z(0x13), Z(0xa0), Z(0xa8), Z(0x4c), Z(0x0d), Z(0x6c), Z(0x2f),
0212     Z(0x47), Z(0x13), Z(0x13), Z(0x52), Z(0x1f), Z(0x2d), Z(0xf5), Z(0x79),
0213     Z(0x3d), Z(0xa2), Z(0x54), Z(0xbd), Z(0x69), Z(0xc8), Z(0x6b), Z(0xf3),
0214     Z(0x05), Z(0x28), Z(0xf1), Z(0x16), Z(0x46), Z(0x40), Z(0xb0), Z(0x11),
0215     Z(0xd3), Z(0xb7), Z(0x95), Z(0x49), Z(0xcf), Z(0xc3), Z(0x1d), Z(0x8f),
0216     Z(0xd8), Z(0xe1), Z(0x73), Z(0xdb), Z(0xad), Z(0xc8), Z(0xc9), Z(0xa9),
0217     Z(0xa1), Z(0xc2), Z(0xc5), Z(0xe3), Z(0xba), Z(0xfc), Z(0x0e), Z(0x25)
0218 };
0219 
0220 /*
0221  * This is a 16 round Feistel network with permutation F_ENCRYPT
0222  */
0223 #define F_ENCRYPT(R, L, sched)                      \
0224 do {                                    \
0225     union lc4 { __be32 l; u8 c[4]; } u;             \
0226     u.l = sched ^ R;                        \
0227     L ^= sbox0[u.c[0]] ^ sbox1[u.c[1]] ^ sbox2[u.c[2]] ^ sbox3[u.c[3]]; \
0228 } while (0)
0229 
0230 /*
0231  * encryptor
0232  */
0233 static void fcrypt_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0234 {
0235     const struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm);
0236     struct {
0237         __be32 l, r;
0238     } X;
0239 
0240     memcpy(&X, src, sizeof(X));
0241 
0242     F_ENCRYPT(X.r, X.l, ctx->sched[0x0]);
0243     F_ENCRYPT(X.l, X.r, ctx->sched[0x1]);
0244     F_ENCRYPT(X.r, X.l, ctx->sched[0x2]);
0245     F_ENCRYPT(X.l, X.r, ctx->sched[0x3]);
0246     F_ENCRYPT(X.r, X.l, ctx->sched[0x4]);
0247     F_ENCRYPT(X.l, X.r, ctx->sched[0x5]);
0248     F_ENCRYPT(X.r, X.l, ctx->sched[0x6]);
0249     F_ENCRYPT(X.l, X.r, ctx->sched[0x7]);
0250     F_ENCRYPT(X.r, X.l, ctx->sched[0x8]);
0251     F_ENCRYPT(X.l, X.r, ctx->sched[0x9]);
0252     F_ENCRYPT(X.r, X.l, ctx->sched[0xa]);
0253     F_ENCRYPT(X.l, X.r, ctx->sched[0xb]);
0254     F_ENCRYPT(X.r, X.l, ctx->sched[0xc]);
0255     F_ENCRYPT(X.l, X.r, ctx->sched[0xd]);
0256     F_ENCRYPT(X.r, X.l, ctx->sched[0xe]);
0257     F_ENCRYPT(X.l, X.r, ctx->sched[0xf]);
0258 
0259     memcpy(dst, &X, sizeof(X));
0260 }
0261 
0262 /*
0263  * decryptor
0264  */
0265 static void fcrypt_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0266 {
0267     const struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm);
0268     struct {
0269         __be32 l, r;
0270     } X;
0271 
0272     memcpy(&X, src, sizeof(X));
0273 
0274     F_ENCRYPT(X.l, X.r, ctx->sched[0xf]);
0275     F_ENCRYPT(X.r, X.l, ctx->sched[0xe]);
0276     F_ENCRYPT(X.l, X.r, ctx->sched[0xd]);
0277     F_ENCRYPT(X.r, X.l, ctx->sched[0xc]);
0278     F_ENCRYPT(X.l, X.r, ctx->sched[0xb]);
0279     F_ENCRYPT(X.r, X.l, ctx->sched[0xa]);
0280     F_ENCRYPT(X.l, X.r, ctx->sched[0x9]);
0281     F_ENCRYPT(X.r, X.l, ctx->sched[0x8]);
0282     F_ENCRYPT(X.l, X.r, ctx->sched[0x7]);
0283     F_ENCRYPT(X.r, X.l, ctx->sched[0x6]);
0284     F_ENCRYPT(X.l, X.r, ctx->sched[0x5]);
0285     F_ENCRYPT(X.r, X.l, ctx->sched[0x4]);
0286     F_ENCRYPT(X.l, X.r, ctx->sched[0x3]);
0287     F_ENCRYPT(X.r, X.l, ctx->sched[0x2]);
0288     F_ENCRYPT(X.l, X.r, ctx->sched[0x1]);
0289     F_ENCRYPT(X.r, X.l, ctx->sched[0x0]);
0290 
0291     memcpy(dst, &X, sizeof(X));
0292 }
0293 
0294 /*
0295  * Generate a key schedule from key, the least significant bit in each key byte
0296  * is parity and shall be ignored. This leaves 56 significant bits in the key
0297  * to scatter over the 16 key schedules. For each schedule extract the low
0298  * order 32 bits and use as schedule, then rotate right by 11 bits.
0299  */
0300 static int fcrypt_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
0301 {
0302     struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm);
0303 
0304 #if BITS_PER_LONG == 64  /* the 64-bit version can also be used for 32-bit
0305               * kernels - it seems to be faster but the code is
0306               * larger */
0307 
0308     u64 k;  /* k holds all 56 non-parity bits */
0309 
0310     /* discard the parity bits */
0311     k = (*key++) >> 1;
0312     k <<= 7;
0313     k |= (*key++) >> 1;
0314     k <<= 7;
0315     k |= (*key++) >> 1;
0316     k <<= 7;
0317     k |= (*key++) >> 1;
0318     k <<= 7;
0319     k |= (*key++) >> 1;
0320     k <<= 7;
0321     k |= (*key++) >> 1;
0322     k <<= 7;
0323     k |= (*key++) >> 1;
0324     k <<= 7;
0325     k |= (*key) >> 1;
0326 
0327     /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
0328     ctx->sched[0x0] = cpu_to_be32(k); ror56_64(k, 11);
0329     ctx->sched[0x1] = cpu_to_be32(k); ror56_64(k, 11);
0330     ctx->sched[0x2] = cpu_to_be32(k); ror56_64(k, 11);
0331     ctx->sched[0x3] = cpu_to_be32(k); ror56_64(k, 11);
0332     ctx->sched[0x4] = cpu_to_be32(k); ror56_64(k, 11);
0333     ctx->sched[0x5] = cpu_to_be32(k); ror56_64(k, 11);
0334     ctx->sched[0x6] = cpu_to_be32(k); ror56_64(k, 11);
0335     ctx->sched[0x7] = cpu_to_be32(k); ror56_64(k, 11);
0336     ctx->sched[0x8] = cpu_to_be32(k); ror56_64(k, 11);
0337     ctx->sched[0x9] = cpu_to_be32(k); ror56_64(k, 11);
0338     ctx->sched[0xa] = cpu_to_be32(k); ror56_64(k, 11);
0339     ctx->sched[0xb] = cpu_to_be32(k); ror56_64(k, 11);
0340     ctx->sched[0xc] = cpu_to_be32(k); ror56_64(k, 11);
0341     ctx->sched[0xd] = cpu_to_be32(k); ror56_64(k, 11);
0342     ctx->sched[0xe] = cpu_to_be32(k); ror56_64(k, 11);
0343     ctx->sched[0xf] = cpu_to_be32(k);
0344 
0345     return 0;
0346 #else
0347     u32 hi, lo;     /* hi is upper 24 bits and lo lower 32, total 56 */
0348 
0349     /* discard the parity bits */
0350     lo = (*key++) >> 1;
0351     lo <<= 7;
0352     lo |= (*key++) >> 1;
0353     lo <<= 7;
0354     lo |= (*key++) >> 1;
0355     lo <<= 7;
0356     lo |= (*key++) >> 1;
0357     hi = lo >> 4;
0358     lo &= 0xf;
0359     lo <<= 7;
0360     lo |= (*key++) >> 1;
0361     lo <<= 7;
0362     lo |= (*key++) >> 1;
0363     lo <<= 7;
0364     lo |= (*key++) >> 1;
0365     lo <<= 7;
0366     lo |= (*key) >> 1;
0367 
0368     /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
0369     ctx->sched[0x0] = cpu_to_be32(lo); ror56(hi, lo, 11);
0370     ctx->sched[0x1] = cpu_to_be32(lo); ror56(hi, lo, 11);
0371     ctx->sched[0x2] = cpu_to_be32(lo); ror56(hi, lo, 11);
0372     ctx->sched[0x3] = cpu_to_be32(lo); ror56(hi, lo, 11);
0373     ctx->sched[0x4] = cpu_to_be32(lo); ror56(hi, lo, 11);
0374     ctx->sched[0x5] = cpu_to_be32(lo); ror56(hi, lo, 11);
0375     ctx->sched[0x6] = cpu_to_be32(lo); ror56(hi, lo, 11);
0376     ctx->sched[0x7] = cpu_to_be32(lo); ror56(hi, lo, 11);
0377     ctx->sched[0x8] = cpu_to_be32(lo); ror56(hi, lo, 11);
0378     ctx->sched[0x9] = cpu_to_be32(lo); ror56(hi, lo, 11);
0379     ctx->sched[0xa] = cpu_to_be32(lo); ror56(hi, lo, 11);
0380     ctx->sched[0xb] = cpu_to_be32(lo); ror56(hi, lo, 11);
0381     ctx->sched[0xc] = cpu_to_be32(lo); ror56(hi, lo, 11);
0382     ctx->sched[0xd] = cpu_to_be32(lo); ror56(hi, lo, 11);
0383     ctx->sched[0xe] = cpu_to_be32(lo); ror56(hi, lo, 11);
0384     ctx->sched[0xf] = cpu_to_be32(lo);
0385     return 0;
0386 #endif
0387 }
0388 
0389 static struct crypto_alg fcrypt_alg = {
0390     .cra_name       =   "fcrypt",
0391     .cra_driver_name    =   "fcrypt-generic",
0392     .cra_flags      =   CRYPTO_ALG_TYPE_CIPHER,
0393     .cra_blocksize      =   8,
0394     .cra_ctxsize        =   sizeof(struct fcrypt_ctx),
0395     .cra_module     =   THIS_MODULE,
0396     .cra_u          =   { .cipher = {
0397     .cia_min_keysize    =   8,
0398     .cia_max_keysize    =   8,
0399     .cia_setkey     =   fcrypt_setkey,
0400     .cia_encrypt        =   fcrypt_encrypt,
0401     .cia_decrypt        =   fcrypt_decrypt } }
0402 };
0403 
0404 static int __init fcrypt_mod_init(void)
0405 {
0406     return crypto_register_alg(&fcrypt_alg);
0407 }
0408 
0409 static void __exit fcrypt_mod_fini(void)
0410 {
0411     crypto_unregister_alg(&fcrypt_alg);
0412 }
0413 
0414 subsys_initcall(fcrypt_mod_init);
0415 module_exit(fcrypt_mod_fini);
0416 
0417 MODULE_LICENSE("Dual BSD/GPL");
0418 MODULE_DESCRIPTION("FCrypt Cipher Algorithm");
0419 MODULE_AUTHOR("David Howells <dhowells@redhat.com>");
0420 MODULE_ALIAS_CRYPTO("fcrypt");