1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #include <sys/types.h>
  27 #include <sys/systm.h>
  28 #include <sys/ddi.h>
  29 #include <sys/sysmacros.h>
  30 #include <sys/strsun.h>
  31 #include <sys/crypto/spi.h>
  32 #include <modes/modes.h>
  33 #include <sys/crypto/common.h>
  34 #include "des_impl.h"
  35 #ifndef _KERNEL
  36 #include <strings.h>
  37 #include <stdlib.h>
  38 #endif  /* !_KERNEL */
  39 
  40 #if defined(__i386) || defined(__amd64)
  41 #include <sys/byteorder.h>
  42 #define UNALIGNED_POINTERS_PERMITTED
  43 #endif
  44 
  45 typedef struct keysched_s {
  46         uint64_t ksch_encrypt[16];
  47         uint64_t ksch_decrypt[16];
  48 } keysched_t;
  49 
  50 typedef struct keysched3_s {
  51         uint64_t ksch_encrypt[48];
  52         uint64_t ksch_decrypt[48];
  53 } keysched3_t;
  54 
  55 static void fix_des_parity(uint64_t *);
  56 
  57 #ifndef sun4u
  58 
  59 static const uint64_t sbox_table[8][64]=
  60 {
  61 /* BEGIN CSTYLED */
  62 {
  63 0x0000140140020000ULL, 0x0000000000000000ULL, 0x0000000140000000ULL, 0x0000140140020020ULL,
  64 0x0000140140000020ULL, 0x0000000140020020ULL, 0x0000000000000020ULL, 0x0000000140000000ULL,
  65 0x0000000000020000ULL, 0x0000140140020000ULL, 0x0000140140020020ULL, 0x0000000000020000ULL,
  66 0x0000140000020020ULL, 0x0000140140000020ULL, 0x0000140000000000ULL, 0x0000000000000020ULL,
  67 0x0000000000020020ULL, 0x0000140000020000ULL, 0x0000140000020000ULL, 0x0000000140020000ULL,
  68 0x0000000140020000ULL, 0x0000140140000000ULL, 0x0000140140000000ULL, 0x0000140000020020ULL,
  69 0x0000000140000020ULL, 0x0000140000000020ULL, 0x0000140000000020ULL, 0x0000000140000020ULL,
  70 0x0000000000000000ULL, 0x0000000000020020ULL, 0x0000000140020020ULL, 0x0000140000000000ULL,
  71 0x0000000140000000ULL, 0x0000140140020020ULL, 0x0000000000000020ULL, 0x0000140140000000ULL,
  72 0x0000140140020000ULL, 0x0000140000000000ULL, 0x0000140000000000ULL, 0x0000000000020000ULL,
  73 0x0000140140000020ULL, 0x0000000140000000ULL, 0x0000000140020000ULL, 0x0000140000000020ULL,
  74 0x0000000000020000ULL, 0x0000000000000020ULL, 0x0000140000020020ULL, 0x0000000140020020ULL,
  75 0x0000140140020020ULL, 0x0000000140000020ULL, 0x0000140140000000ULL, 0x0000140000020020ULL,
  76 0x0000140000000020ULL, 0x0000000000020020ULL, 0x0000000140020020ULL, 0x0000140140020000ULL,
  77 0x0000000000020020ULL, 0x0000140000020000ULL, 0x0000140000020000ULL, 0x0000000000000000ULL,
  78 0x0000000140000020ULL, 0x0000000140020000ULL, 0x0000000000000000ULL, 0x0000140140000020ULL
  79 },
  80 {
  81 0x2000005020000500ULL, 0x2000000020000000ULL, 0x0000000020000000ULL, 0x0000005020000500ULL,
  82 0x0000005000000000ULL, 0x0000000000000500ULL, 0x2000005000000500ULL, 0x2000000020000500ULL,
  83 0x2000000000000500ULL, 0x2000005020000500ULL, 0x2000005020000000ULL, 0x2000000000000000ULL,
  84 0x2000000020000000ULL, 0x0000005000000000ULL, 0x0000000000000500ULL, 0x2000005000000500ULL,
  85 0x0000005020000000ULL, 0x0000005000000500ULL, 0x2000000020000500ULL, 0x0000000000000000ULL,
  86 0x2000000000000000ULL, 0x0000000020000000ULL, 0x0000005020000500ULL, 0x2000005000000000ULL,
  87 0x0000005000000500ULL, 0x2000000000000500ULL, 0x0000000000000000ULL, 0x0000005020000000ULL,
  88 0x0000000020000500ULL, 0x2000005020000000ULL, 0x2000005000000000ULL, 0x0000000020000500ULL,
  89 0x0000000000000000ULL, 0x0000005020000500ULL, 0x2000005000000500ULL, 0x0000005000000000ULL,
  90 0x2000000020000500ULL, 0x2000005000000000ULL, 0x2000005020000000ULL, 0x0000000020000000ULL,
  91 0x2000005000000000ULL, 0x2000000020000000ULL, 0x0000000000000500ULL, 0x2000005020000500ULL,
  92 0x0000005020000500ULL, 0x0000000000000500ULL, 0x0000000020000000ULL, 0x2000000000000000ULL,
  93 0x0000000020000500ULL, 0x2000005020000000ULL, 0x0000005000000000ULL, 0x2000000000000500ULL,
  94 0x0000005000000500ULL, 0x2000000020000500ULL, 0x2000000000000500ULL, 0x0000005000000500ULL,
  95 0x0000005020000000ULL, 0x0000000000000000ULL, 0x2000000020000000ULL, 0x0000000020000500ULL,
  96 0x2000000000000000ULL, 0x2000005000000500ULL, 0x2000005020000500ULL, 0x0000005020000000ULL
  97 },
  98 {
  99 0x0000000000014040ULL, 0x0000800280014000ULL, 0x0000000000000000ULL, 0x0000800280000040ULL,
 100 0x0000800000014000ULL, 0x0000000000000000ULL, 0x0000000280014040ULL, 0x0000800000014000ULL,
 101 0x0000000280000040ULL, 0x0000800000000040ULL, 0x0000800000000040ULL, 0x0000000280000000ULL,
 102 0x0000800280014040ULL, 0x0000000280000040ULL, 0x0000800280000000ULL, 0x0000000000014040ULL,
 103 0x0000800000000000ULL, 0x0000000000000040ULL, 0x0000800280014000ULL, 0x0000000000014000ULL,
 104 0x0000000280014000ULL, 0x0000800280000000ULL, 0x0000800280000040ULL, 0x0000000280014040ULL,
 105 0x0000800000014040ULL, 0x0000000280014000ULL, 0x0000000280000000ULL, 0x0000800000014040ULL,
 106 0x0000000000000040ULL, 0x0000800280014040ULL, 0x0000000000014000ULL, 0x0000800000000000ULL,
 107 0x0000800280014000ULL, 0x0000800000000000ULL, 0x0000000280000040ULL, 0x0000000000014040ULL,
 108 0x0000000280000000ULL, 0x0000800280014000ULL, 0x0000800000014000ULL, 0x0000000000000000ULL,
 109 0x0000000000014000ULL, 0x0000000280000040ULL, 0x0000800280014040ULL, 0x0000800000014000ULL,
 110 0x0000800000000040ULL, 0x0000000000014000ULL, 0x0000000000000000ULL, 0x0000800280000040ULL,
 111 0x0000800000014040ULL, 0x0000000280000000ULL, 0x0000800000000000ULL, 0x0000800280014040ULL,
 112 0x0000000000000040ULL, 0x0000000280014040ULL, 0x0000000280014000ULL, 0x0000800000000040ULL,
 113 0x0000800280000000ULL, 0x0000800000014040ULL, 0x0000000000014040ULL, 0x0000800280000000ULL,
 114 0x0000000280014040ULL, 0x0000000000000040ULL, 0x0000800280000040ULL, 0x0000000280014000ULL
 115 },
 116 {
 117 0x4000020008100008ULL, 0x4000000008101008ULL, 0x4000000008101008ULL, 0x0000000000001000ULL,
 118 0x0000020008101000ULL, 0x4000020000001008ULL, 0x4000020000000008ULL, 0x4000000008100008ULL,
 119 0x0000000000000000ULL, 0x0000020008100000ULL, 0x0000020008100000ULL, 0x4000020008101008ULL,
 120 0x4000000000001008ULL, 0x0000000000000000ULL, 0x0000020000001000ULL, 0x4000020000000008ULL,
 121 0x4000000000000008ULL, 0x0000000008100000ULL, 0x0000020000000000ULL, 0x4000020008100008ULL,
 122 0x0000000000001000ULL, 0x0000020000000000ULL, 0x4000000008100008ULL, 0x0000000008101000ULL,
 123 0x4000020000001008ULL, 0x4000000000000008ULL, 0x0000000008101000ULL, 0x0000020000001000ULL,
 124 0x0000000008100000ULL, 0x0000020008101000ULL, 0x4000020008101008ULL, 0x4000000000001008ULL,
 125 0x0000020000001000ULL, 0x4000020000000008ULL, 0x0000020008100000ULL, 0x4000020008101008ULL,
 126 0x4000000000001008ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000020008100000ULL,
 127 0x0000000008101000ULL, 0x0000020000001000ULL, 0x4000020000001008ULL, 0x4000000000000008ULL,
 128 0x4000020008100008ULL, 0x4000000008101008ULL, 0x4000000008101008ULL, 0x0000000000001000ULL,
 129 0x4000020008101008ULL, 0x4000000000001008ULL, 0x4000000000000008ULL, 0x0000000008100000ULL,
 130 0x4000020000000008ULL, 0x4000000008100008ULL, 0x0000020008101000ULL, 0x4000020000001008ULL,
 131 0x4000000008100008ULL, 0x0000000008101000ULL, 0x0000020000000000ULL, 0x4000020008100008ULL,
 132 0x0000000000001000ULL, 0x0000020000000000ULL, 0x0000000008100000ULL, 0x0000020008101000ULL
 133 },
 134 {
 135 0x000000000000a000ULL, 0x000028080000a000ULL, 0x0000280800000000ULL, 0x100028000000a000ULL,
 136 0x0000000800000000ULL, 0x000000000000a000ULL, 0x1000000000000000ULL, 0x0000280800000000ULL,
 137 0x100000080000a000ULL, 0x0000000800000000ULL, 0x000028000000a000ULL, 0x100000080000a000ULL,
 138 0x100028000000a000ULL, 0x1000280800000000ULL, 0x000000080000a000ULL, 0x1000000000000000ULL,
 139 0x0000280000000000ULL, 0x1000000800000000ULL, 0x1000000800000000ULL, 0x0000000000000000ULL,
 140 0x100000000000a000ULL, 0x100028080000a000ULL, 0x100028080000a000ULL, 0x000028000000a000ULL,
 141 0x1000280800000000ULL, 0x100000000000a000ULL, 0x0000000000000000ULL, 0x1000280000000000ULL,
 142 0x000028080000a000ULL, 0x0000280000000000ULL, 0x1000280000000000ULL, 0x000000080000a000ULL,
 143 0x0000000800000000ULL, 0x100028000000a000ULL, 0x000000000000a000ULL, 0x0000280000000000ULL,
 144 0x1000000000000000ULL, 0x0000280800000000ULL, 0x100028000000a000ULL, 0x100000080000a000ULL,
 145 0x000028000000a000ULL, 0x1000000000000000ULL, 0x1000280800000000ULL, 0x000028080000a000ULL,
 146 0x100000080000a000ULL, 0x000000000000a000ULL, 0x0000280000000000ULL, 0x1000280800000000ULL,
 147 0x100028080000a000ULL, 0x000000080000a000ULL, 0x1000280000000000ULL, 0x100028080000a000ULL,
 148 0x0000280800000000ULL, 0x0000000000000000ULL, 0x1000000800000000ULL, 0x1000280000000000ULL,
 149 0x000000080000a000ULL, 0x000028000000a000ULL, 0x100000000000a000ULL, 0x0000000800000000ULL,
 150 0x0000000000000000ULL, 0x1000000800000000ULL, 0x000028080000a000ULL, 0x100000000000a000ULL
 151 },
 152 {
 153 0x0802000000000280ULL, 0x0802010000000000ULL, 0x0000000010000000ULL, 0x0802010010000280ULL,
 154 0x0802010000000000ULL, 0x0000000000000280ULL, 0x0802010010000280ULL, 0x0000010000000000ULL,
 155 0x0802000010000000ULL, 0x0000010010000280ULL, 0x0000010000000000ULL, 0x0802000000000280ULL,
 156 0x0000010000000280ULL, 0x0802000010000000ULL, 0x0802000000000000ULL, 0x0000000010000280ULL,
 157 0x0000000000000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL, 0x0000000010000000ULL,
 158 0x0000010010000000ULL, 0x0802000010000280ULL, 0x0000000000000280ULL, 0x0802010000000280ULL,
 159 0x0802010000000280ULL, 0x0000000000000000ULL, 0x0000010010000280ULL, 0x0802010010000000ULL,
 160 0x0000000010000280ULL, 0x0000010010000000ULL, 0x0802010010000000ULL, 0x0802000000000000ULL,
 161 0x0802000010000000ULL, 0x0000000000000280ULL, 0x0802010000000280ULL, 0x0000010010000000ULL,
 162 0x0802010010000280ULL, 0x0000010000000000ULL, 0x0000000010000280ULL, 0x0802000000000280ULL,
 163 0x0000010000000000ULL, 0x0802000010000000ULL, 0x0802000000000000ULL, 0x0000000010000280ULL,
 164 0x0802000000000280ULL, 0x0802010010000280ULL, 0x0000010010000000ULL, 0x0802010000000000ULL,
 165 0x0000010010000280ULL, 0x0802010010000000ULL, 0x0000000000000000ULL, 0x0802010000000280ULL,
 166 0x0000000000000280ULL, 0x0000000010000000ULL, 0x0802010000000000ULL, 0x0000010010000280ULL,
 167 0x0000000010000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL, 0x0000000000000000ULL,
 168 0x0802010010000000ULL, 0x0802000000000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL
 169 },
 170 {
 171 0x000000a000000000ULL, 0x800040a000000010ULL, 0x8000400000040010ULL, 0x0000000000000000ULL,
 172 0x0000000000040000ULL, 0x8000400000040010ULL, 0x800000a000040010ULL, 0x000040a000040000ULL,
 173 0x800040a000040010ULL, 0x000000a000000000ULL, 0x0000000000000000ULL, 0x8000400000000010ULL,
 174 0x8000000000000010ULL, 0x0000400000000000ULL, 0x800040a000000010ULL, 0x8000000000040010ULL,
 175 0x0000400000040000ULL, 0x800000a000040010ULL, 0x800000a000000010ULL, 0x0000400000040000ULL,
 176 0x8000400000000010ULL, 0x000040a000000000ULL, 0x000040a000040000ULL, 0x800000a000000010ULL,
 177 0x000040a000000000ULL, 0x0000000000040000ULL, 0x8000000000040010ULL, 0x800040a000040010ULL,
 178 0x000000a000040000ULL, 0x8000000000000010ULL, 0x0000400000000000ULL, 0x000000a000040000ULL,
 179 0x0000400000000000ULL, 0x000000a000040000ULL, 0x000000a000000000ULL, 0x8000400000040010ULL,
 180 0x8000400000040010ULL, 0x800040a000000010ULL, 0x800040a000000010ULL, 0x8000000000000010ULL,
 181 0x800000a000000010ULL, 0x0000400000000000ULL, 0x0000400000040000ULL, 0x000000a000000000ULL,
 182 0x000040a000040000ULL, 0x8000000000040010ULL, 0x800000a000040010ULL, 0x000040a000040000ULL,
 183 0x8000000000040010ULL, 0x8000400000000010ULL, 0x800040a000040010ULL, 0x000040a000000000ULL,
 184 0x000000a000040000ULL, 0x0000000000000000ULL, 0x8000000000000010ULL, 0x800040a000040010ULL,
 185 0x0000000000000000ULL, 0x800000a000040010ULL, 0x000040a000000000ULL, 0x0000000000040000ULL,
 186 0x8000400000000010ULL, 0x0000400000040000ULL, 0x0000000000040000ULL, 0x800000a000000010ULL
 187 },
 188 {
 189 0x0401000004080800ULL, 0x0000000004080000ULL, 0x0000000400000000ULL, 0x0401000404080800ULL,
 190 0x0401000000000000ULL, 0x0401000004080800ULL, 0x0000000000000800ULL, 0x0401000000000000ULL,
 191 0x0000000400000800ULL, 0x0401000400000000ULL, 0x0401000404080800ULL, 0x0000000404080000ULL,
 192 0x0401000404080000ULL, 0x0000000404080800ULL, 0x0000000004080000ULL, 0x0000000000000800ULL,
 193 0x0401000400000000ULL, 0x0401000000000800ULL, 0x0401000004080000ULL, 0x0000000004080800ULL,
 194 0x0000000404080000ULL, 0x0000000400000800ULL, 0x0401000400000800ULL, 0x0401000404080000ULL,
 195 0x0000000004080800ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0401000400000800ULL,
 196 0x0401000000000800ULL, 0x0401000004080000ULL, 0x0000000404080800ULL, 0x0000000400000000ULL,
 197 0x0000000404080800ULL, 0x0000000400000000ULL, 0x0401000404080000ULL, 0x0000000004080000ULL,
 198 0x0000000000000800ULL, 0x0401000400000800ULL, 0x0000000004080000ULL, 0x0000000404080800ULL,
 199 0x0401000004080000ULL, 0x0000000000000800ULL, 0x0401000000000800ULL, 0x0401000400000000ULL,
 200 0x0401000400000800ULL, 0x0401000000000000ULL, 0x0000000400000000ULL, 0x0401000004080800ULL,
 201 0x0000000000000000ULL, 0x0401000404080800ULL, 0x0000000400000800ULL, 0x0401000000000800ULL,
 202 0x0401000400000000ULL, 0x0401000004080000ULL, 0x0401000004080800ULL, 0x0000000000000000ULL,
 203 0x0401000404080800ULL, 0x0000000404080000ULL, 0x0000000404080000ULL, 0x0000000004080800ULL,
 204 0x0000000004080800ULL, 0x0000000400000800ULL, 0x0401000000000000ULL, 0x0401000404080000ULL
 205 }
 206 /* END CSTYLED */
 207 };
 208 
 209 
 210 static const uint64_t ip_table[2][256]=
 211 {
 212 /* BEGIN CSTYLED */
 213 {
 214 0x0000000000000000ULL, 0x0000000000000400ULL, 0x0080000000000280ULL, 0x0080000000000680ULL,
 215 0x0000000000400000ULL, 0x0000000000400400ULL, 0x0080000000400280ULL, 0x0080000000400680ULL,
 216 0x0000000000280000ULL, 0x0000000000280400ULL, 0x0080000000280280ULL, 0x0080000000280680ULL,
 217 0x0000000000680000ULL, 0x0000000000680400ULL, 0x0080000000680280ULL, 0x0080000000680680ULL,
 218 0x0000000400000000ULL, 0x0000000400000400ULL, 0x0080000400000280ULL, 0x0080000400000680ULL,
 219 0x0000000400400000ULL, 0x0000000400400400ULL, 0x0080000400400280ULL, 0x0080000400400680ULL,
 220 0x0000000400280000ULL, 0x0000000400280400ULL, 0x0080000400280280ULL, 0x0080000400280680ULL,
 221 0x0000000400680000ULL, 0x0000000400680400ULL, 0x0080000400680280ULL, 0x0080000400680680ULL,
 222 0x0000000280000000ULL, 0x0000000280000400ULL, 0x0080000280000280ULL, 0x0080000280000680ULL,
 223 0x0000000280400000ULL, 0x0000000280400400ULL, 0x0080000280400280ULL, 0x0080000280400680ULL,
 224 0x0000000280280000ULL, 0x0000000280280400ULL, 0x0080000280280280ULL, 0x0080000280280680ULL,
 225 0x0000000280680000ULL, 0x0000000280680400ULL, 0x0080000280680280ULL, 0x0080000280680680ULL,
 226 0x0000000680000000ULL, 0x0000000680000400ULL, 0x0080000680000280ULL, 0x0080000680000680ULL,
 227 0x0000000680400000ULL, 0x0000000680400400ULL, 0x0080000680400280ULL, 0x0080000680400680ULL,
 228 0x0000000680280000ULL, 0x0000000680280400ULL, 0x0080000680280280ULL, 0x0080000680280680ULL,
 229 0x0000000680680000ULL, 0x0000000680680400ULL, 0x0080000680680280ULL, 0x0080000680680680ULL,
 230 0x0000400000000000ULL, 0x0000400000000400ULL, 0x0080400000000280ULL, 0x0080400000000680ULL,
 231 0x0000400000400000ULL, 0x0000400000400400ULL, 0x0080400000400280ULL, 0x0080400000400680ULL,
 232 0x0000400000280000ULL, 0x0000400000280400ULL, 0x0080400000280280ULL, 0x0080400000280680ULL,
 233 0x0000400000680000ULL, 0x0000400000680400ULL, 0x0080400000680280ULL, 0x0080400000680680ULL,
 234 0x0000400400000000ULL, 0x0000400400000400ULL, 0x0080400400000280ULL, 0x0080400400000680ULL,
 235 0x0000400400400000ULL, 0x0000400400400400ULL, 0x0080400400400280ULL, 0x0080400400400680ULL,
 236 0x0000400400280000ULL, 0x0000400400280400ULL, 0x0080400400280280ULL, 0x0080400400280680ULL,
 237 0x0000400400680000ULL, 0x0000400400680400ULL, 0x0080400400680280ULL, 0x0080400400680680ULL,
 238 0x0000400280000000ULL, 0x0000400280000400ULL, 0x0080400280000280ULL, 0x0080400280000680ULL,
 239 0x0000400280400000ULL, 0x0000400280400400ULL, 0x0080400280400280ULL, 0x0080400280400680ULL,
 240 0x0000400280280000ULL, 0x0000400280280400ULL, 0x0080400280280280ULL, 0x0080400280280680ULL,
 241 0x0000400280680000ULL, 0x0000400280680400ULL, 0x0080400280680280ULL, 0x0080400280680680ULL,
 242 0x0000400680000000ULL, 0x0000400680000400ULL, 0x0080400680000280ULL, 0x0080400680000680ULL,
 243 0x0000400680400000ULL, 0x0000400680400400ULL, 0x0080400680400280ULL, 0x0080400680400680ULL,
 244 0x0000400680280000ULL, 0x0000400680280400ULL, 0x0080400680280280ULL, 0x0080400680280680ULL,
 245 0x0000400680680000ULL, 0x0000400680680400ULL, 0x0080400680680280ULL, 0x0080400680680680ULL,
 246 0x0000280000000000ULL, 0x0000280000000400ULL, 0x0080280000000280ULL, 0x0080280000000680ULL,
 247 0x0000280000400000ULL, 0x0000280000400400ULL, 0x0080280000400280ULL, 0x0080280000400680ULL,
 248 0x0000280000280000ULL, 0x0000280000280400ULL, 0x0080280000280280ULL, 0x0080280000280680ULL,
 249 0x0000280000680000ULL, 0x0000280000680400ULL, 0x0080280000680280ULL, 0x0080280000680680ULL,
 250 0x0000280400000000ULL, 0x0000280400000400ULL, 0x0080280400000280ULL, 0x0080280400000680ULL,
 251 0x0000280400400000ULL, 0x0000280400400400ULL, 0x0080280400400280ULL, 0x0080280400400680ULL,
 252 0x0000280400280000ULL, 0x0000280400280400ULL, 0x0080280400280280ULL, 0x0080280400280680ULL,
 253 0x0000280400680000ULL, 0x0000280400680400ULL, 0x0080280400680280ULL, 0x0080280400680680ULL,
 254 0x0000280280000000ULL, 0x0000280280000400ULL, 0x0080280280000280ULL, 0x0080280280000680ULL,
 255 0x0000280280400000ULL, 0x0000280280400400ULL, 0x0080280280400280ULL, 0x0080280280400680ULL,
 256 0x0000280280280000ULL, 0x0000280280280400ULL, 0x0080280280280280ULL, 0x0080280280280680ULL,
 257 0x0000280280680000ULL, 0x0000280280680400ULL, 0x0080280280680280ULL, 0x0080280280680680ULL,
 258 0x0000280680000000ULL, 0x0000280680000400ULL, 0x0080280680000280ULL, 0x0080280680000680ULL,
 259 0x0000280680400000ULL, 0x0000280680400400ULL, 0x0080280680400280ULL, 0x0080280680400680ULL,
 260 0x0000280680280000ULL, 0x0000280680280400ULL, 0x0080280680280280ULL, 0x0080280680280680ULL,
 261 0x0000280680680000ULL, 0x0000280680680400ULL, 0x0080280680680280ULL, 0x0080280680680680ULL,
 262 0x0000680000000000ULL, 0x0000680000000400ULL, 0x0080680000000280ULL, 0x0080680000000680ULL,
 263 0x0000680000400000ULL, 0x0000680000400400ULL, 0x0080680000400280ULL, 0x0080680000400680ULL,
 264 0x0000680000280000ULL, 0x0000680000280400ULL, 0x0080680000280280ULL, 0x0080680000280680ULL,
 265 0x0000680000680000ULL, 0x0000680000680400ULL, 0x0080680000680280ULL, 0x0080680000680680ULL,
 266 0x0000680400000000ULL, 0x0000680400000400ULL, 0x0080680400000280ULL, 0x0080680400000680ULL,
 267 0x0000680400400000ULL, 0x0000680400400400ULL, 0x0080680400400280ULL, 0x0080680400400680ULL,
 268 0x0000680400280000ULL, 0x0000680400280400ULL, 0x0080680400280280ULL, 0x0080680400280680ULL,
 269 0x0000680400680000ULL, 0x0000680400680400ULL, 0x0080680400680280ULL, 0x0080680400680680ULL,
 270 0x0000680280000000ULL, 0x0000680280000400ULL, 0x0080680280000280ULL, 0x0080680280000680ULL,
 271 0x0000680280400000ULL, 0x0000680280400400ULL, 0x0080680280400280ULL, 0x0080680280400680ULL,
 272 0x0000680280280000ULL, 0x0000680280280400ULL, 0x0080680280280280ULL, 0x0080680280280680ULL,
 273 0x0000680280680000ULL, 0x0000680280680400ULL, 0x0080680280680280ULL, 0x0080680280680680ULL,
 274 0x0000680680000000ULL, 0x0000680680000400ULL, 0x0080680680000280ULL, 0x0080680680000680ULL,
 275 0x0000680680400000ULL, 0x0000680680400400ULL, 0x0080680680400280ULL, 0x0080680680400680ULL,
 276 0x0000680680280000ULL, 0x0000680680280400ULL, 0x0080680680280280ULL, 0x0080680680280680ULL,
 277 0x0000680680680000ULL, 0x0000680680680400ULL, 0x0080680680680280ULL, 0x0080680680680680ULL
 278 },
 279 {
 280 0x0000000000000000ULL, 0x0000000000005000ULL, 0x0000000000000800ULL, 0x0000000000005800ULL,
 281 0x0000000005000000ULL, 0x0000000005005000ULL, 0x0000000005000800ULL, 0x0000000005005800ULL,
 282 0x0000000000800000ULL, 0x0000000000805000ULL, 0x0000000000800800ULL, 0x0000000000805800ULL,
 283 0x0000000005800000ULL, 0x0000000005805000ULL, 0x0000000005800800ULL, 0x0000000005805800ULL,
 284 0x0000005000000000ULL, 0x0000005000005000ULL, 0x0000005000000800ULL, 0x0000005000005800ULL,
 285 0x0000005005000000ULL, 0x0000005005005000ULL, 0x0000005005000800ULL, 0x0000005005005800ULL,
 286 0x0000005000800000ULL, 0x0000005000805000ULL, 0x0000005000800800ULL, 0x0000005000805800ULL,
 287 0x0000005005800000ULL, 0x0000005005805000ULL, 0x0000005005800800ULL, 0x0000005005805800ULL,
 288 0x0000000800000000ULL, 0x0000000800005000ULL, 0x0000000800000800ULL, 0x0000000800005800ULL,
 289 0x0000000805000000ULL, 0x0000000805005000ULL, 0x0000000805000800ULL, 0x0000000805005800ULL,
 290 0x0000000800800000ULL, 0x0000000800805000ULL, 0x0000000800800800ULL, 0x0000000800805800ULL,
 291 0x0000000805800000ULL, 0x0000000805805000ULL, 0x0000000805800800ULL, 0x0000000805805800ULL,
 292 0x0000005800000000ULL, 0x0000005800005000ULL, 0x0000005800000800ULL, 0x0000005800005800ULL,
 293 0x0000005805000000ULL, 0x0000005805005000ULL, 0x0000005805000800ULL, 0x0000005805005800ULL,
 294 0x0000005800800000ULL, 0x0000005800805000ULL, 0x0000005800800800ULL, 0x0000005800805800ULL,
 295 0x0000005805800000ULL, 0x0000005805805000ULL, 0x0000005805800800ULL, 0x0000005805805800ULL,
 296 0x0005000000000004ULL, 0x0005000000005004ULL, 0x0005000000000804ULL, 0x0005000000005804ULL,
 297 0x0005000005000004ULL, 0x0005000005005004ULL, 0x0005000005000804ULL, 0x0005000005005804ULL,
 298 0x0005000000800004ULL, 0x0005000000805004ULL, 0x0005000000800804ULL, 0x0005000000805804ULL,
 299 0x0005000005800004ULL, 0x0005000005805004ULL, 0x0005000005800804ULL, 0x0005000005805804ULL,
 300 0x0005005000000004ULL, 0x0005005000005004ULL, 0x0005005000000804ULL, 0x0005005000005804ULL,
 301 0x0005005005000004ULL, 0x0005005005005004ULL, 0x0005005005000804ULL, 0x0005005005005804ULL,
 302 0x0005005000800004ULL, 0x0005005000805004ULL, 0x0005005000800804ULL, 0x0005005000805804ULL,
 303 0x0005005005800004ULL, 0x0005005005805004ULL, 0x0005005005800804ULL, 0x0005005005805804ULL,
 304 0x0005000800000004ULL, 0x0005000800005004ULL, 0x0005000800000804ULL, 0x0005000800005804ULL,
 305 0x0005000805000004ULL, 0x0005000805005004ULL, 0x0005000805000804ULL, 0x0005000805005804ULL,
 306 0x0005000800800004ULL, 0x0005000800805004ULL, 0x0005000800800804ULL, 0x0005000800805804ULL,
 307 0x0005000805800004ULL, 0x0005000805805004ULL, 0x0005000805800804ULL, 0x0005000805805804ULL,
 308 0x0005005800000004ULL, 0x0005005800005004ULL, 0x0005005800000804ULL, 0x0005005800005804ULL,
 309 0x0005005805000004ULL, 0x0005005805005004ULL, 0x0005005805000804ULL, 0x0005005805005804ULL,
 310 0x0005005800800004ULL, 0x0005005800805004ULL, 0x0005005800800804ULL, 0x0005005800805804ULL,
 311 0x0005005805800004ULL, 0x0005005805805004ULL, 0x0005005805800804ULL, 0x0005005805805804ULL,
 312 0x0000800000000000ULL, 0x0000800000005000ULL, 0x0000800000000800ULL, 0x0000800000005800ULL,
 313 0x0000800005000000ULL, 0x0000800005005000ULL, 0x0000800005000800ULL, 0x0000800005005800ULL,
 314 0x0000800000800000ULL, 0x0000800000805000ULL, 0x0000800000800800ULL, 0x0000800000805800ULL,
 315 0x0000800005800000ULL, 0x0000800005805000ULL, 0x0000800005800800ULL, 0x0000800005805800ULL,
 316 0x0000805000000000ULL, 0x0000805000005000ULL, 0x0000805000000800ULL, 0x0000805000005800ULL,
 317 0x0000805005000000ULL, 0x0000805005005000ULL, 0x0000805005000800ULL, 0x0000805005005800ULL,
 318 0x0000805000800000ULL, 0x0000805000805000ULL, 0x0000805000800800ULL, 0x0000805000805800ULL,
 319 0x0000805005800000ULL, 0x0000805005805000ULL, 0x0000805005800800ULL, 0x0000805005805800ULL,
 320 0x0000800800000000ULL, 0x0000800800005000ULL, 0x0000800800000800ULL, 0x0000800800005800ULL,
 321 0x0000800805000000ULL, 0x0000800805005000ULL, 0x0000800805000800ULL, 0x0000800805005800ULL,
 322 0x0000800800800000ULL, 0x0000800800805000ULL, 0x0000800800800800ULL, 0x0000800800805800ULL,
 323 0x0000800805800000ULL, 0x0000800805805000ULL, 0x0000800805800800ULL, 0x0000800805805800ULL,
 324 0x0000805800000000ULL, 0x0000805800005000ULL, 0x0000805800000800ULL, 0x0000805800005800ULL,
 325 0x0000805805000000ULL, 0x0000805805005000ULL, 0x0000805805000800ULL, 0x0000805805005800ULL,
 326 0x0000805800800000ULL, 0x0000805800805000ULL, 0x0000805800800800ULL, 0x0000805800805800ULL,
 327 0x0000805805800000ULL, 0x0000805805805000ULL, 0x0000805805800800ULL, 0x0000805805805800ULL,
 328 0x0005800000000004ULL, 0x0005800000005004ULL, 0x0005800000000804ULL, 0x0005800000005804ULL,
 329 0x0005800005000004ULL, 0x0005800005005004ULL, 0x0005800005000804ULL, 0x0005800005005804ULL,
 330 0x0005800000800004ULL, 0x0005800000805004ULL, 0x0005800000800804ULL, 0x0005800000805804ULL,
 331 0x0005800005800004ULL, 0x0005800005805004ULL, 0x0005800005800804ULL, 0x0005800005805804ULL,
 332 0x0005805000000004ULL, 0x0005805000005004ULL, 0x0005805000000804ULL, 0x0005805000005804ULL,
 333 0x0005805005000004ULL, 0x0005805005005004ULL, 0x0005805005000804ULL, 0x0005805005005804ULL,
 334 0x0005805000800004ULL, 0x0005805000805004ULL, 0x0005805000800804ULL, 0x0005805000805804ULL,
 335 0x0005805005800004ULL, 0x0005805005805004ULL, 0x0005805005800804ULL, 0x0005805005805804ULL,
 336 0x0005800800000004ULL, 0x0005800800005004ULL, 0x0005800800000804ULL, 0x0005800800005804ULL,
 337 0x0005800805000004ULL, 0x0005800805005004ULL, 0x0005800805000804ULL, 0x0005800805005804ULL,
 338 0x0005800800800004ULL, 0x0005800800805004ULL, 0x0005800800800804ULL, 0x0005800800805804ULL,
 339 0x0005800805800004ULL, 0x0005800805805004ULL, 0x0005800805800804ULL, 0x0005800805805804ULL,
 340 0x0005805800000004ULL, 0x0005805800005004ULL, 0x0005805800000804ULL, 0x0005805800005804ULL,
 341 0x0005805805000004ULL, 0x0005805805005004ULL, 0x0005805805000804ULL, 0x0005805805005804ULL,
 342 0x0005805800800004ULL, 0x0005805800805004ULL, 0x0005805800800804ULL, 0x0005805800805804ULL,
 343 0x0005805805800004ULL, 0x0005805805805004ULL, 0x0005805805800804ULL, 0x0005805805805804ULL
 344 }
 345 /* END CSTYLED */
 346 };
 347 
 348 static const uint32_t fp_table[256]=
 349 {
 350 0x00000000, 0x80000000, 0x00800000, 0x80800000,
 351 0x00008000, 0x80008000, 0x00808000, 0x80808000,
 352 0x00000080, 0x80000080, 0x00800080, 0x80800080,
 353 0x00008080, 0x80008080, 0x00808080, 0x80808080,
 354 0x40000000, 0xc0000000, 0x40800000, 0xc0800000,
 355 0x40008000, 0xc0008000, 0x40808000, 0xc0808000,
 356 0x40000080, 0xc0000080, 0x40800080, 0xc0800080,
 357 0x40008080, 0xc0008080, 0x40808080, 0xc0808080,
 358 0x00400000, 0x80400000, 0x00c00000, 0x80c00000,
 359 0x00408000, 0x80408000, 0x00c08000, 0x80c08000,
 360 0x00400080, 0x80400080, 0x00c00080, 0x80c00080,
 361 0x00408080, 0x80408080, 0x00c08080, 0x80c08080,
 362 0x40400000, 0xc0400000, 0x40c00000, 0xc0c00000,
 363 0x40408000, 0xc0408000, 0x40c08000, 0xc0c08000,
 364 0x40400080, 0xc0400080, 0x40c00080, 0xc0c00080,
 365 0x40408080, 0xc0408080, 0x40c08080, 0xc0c08080,
 366 0x00004000, 0x80004000, 0x00804000, 0x80804000,
 367 0x0000c000, 0x8000c000, 0x0080c000, 0x8080c000,
 368 0x00004080, 0x80004080, 0x00804080, 0x80804080,
 369 0x0000c080, 0x8000c080, 0x0080c080, 0x8080c080,
 370 0x40004000, 0xc0004000, 0x40804000, 0xc0804000,
 371 0x4000c000, 0xc000c000, 0x4080c000, 0xc080c000,
 372 0x40004080, 0xc0004080, 0x40804080, 0xc0804080,
 373 0x4000c080, 0xc000c080, 0x4080c080, 0xc080c080,
 374 0x00404000, 0x80404000, 0x00c04000, 0x80c04000,
 375 0x0040c000, 0x8040c000, 0x00c0c000, 0x80c0c000,
 376 0x00404080, 0x80404080, 0x00c04080, 0x80c04080,
 377 0x0040c080, 0x8040c080, 0x00c0c080, 0x80c0c080,
 378 0x40404000, 0xc0404000, 0x40c04000, 0xc0c04000,
 379 0x4040c000, 0xc040c000, 0x40c0c000, 0xc0c0c000,
 380 0x40404080, 0xc0404080, 0x40c04080, 0xc0c04080,
 381 0x4040c080, 0xc040c080, 0x40c0c080, 0xc0c0c080,
 382 0x00000040, 0x80000040, 0x00800040, 0x80800040,
 383 0x00008040, 0x80008040, 0x00808040, 0x80808040,
 384 0x000000c0, 0x800000c0, 0x008000c0, 0x808000c0,
 385 0x000080c0, 0x800080c0, 0x008080c0, 0x808080c0,
 386 0x40000040, 0xc0000040, 0x40800040, 0xc0800040,
 387 0x40008040, 0xc0008040, 0x40808040, 0xc0808040,
 388 0x400000c0, 0xc00000c0, 0x408000c0, 0xc08000c0,
 389 0x400080c0, 0xc00080c0, 0x408080c0, 0xc08080c0,
 390 0x00400040, 0x80400040, 0x00c00040, 0x80c00040,
 391 0x00408040, 0x80408040, 0x00c08040, 0x80c08040,
 392 0x004000c0, 0x804000c0, 0x00c000c0, 0x80c000c0,
 393 0x004080c0, 0x804080c0, 0x00c080c0, 0x80c080c0,
 394 0x40400040, 0xc0400040, 0x40c00040, 0xc0c00040,
 395 0x40408040, 0xc0408040, 0x40c08040, 0xc0c08040,
 396 0x404000c0, 0xc04000c0, 0x40c000c0, 0xc0c000c0,
 397 0x404080c0, 0xc04080c0, 0x40c080c0, 0xc0c080c0,
 398 0x00004040, 0x80004040, 0x00804040, 0x80804040,
 399 0x0000c040, 0x8000c040, 0x0080c040, 0x8080c040,
 400 0x000040c0, 0x800040c0, 0x008040c0, 0x808040c0,
 401 0x0000c0c0, 0x8000c0c0, 0x0080c0c0, 0x8080c0c0,
 402 0x40004040, 0xc0004040, 0x40804040, 0xc0804040,
 403 0x4000c040, 0xc000c040, 0x4080c040, 0xc080c040,
 404 0x400040c0, 0xc00040c0, 0x408040c0, 0xc08040c0,
 405 0x4000c0c0, 0xc000c0c0, 0x4080c0c0, 0xc080c0c0,
 406 0x00404040, 0x80404040, 0x00c04040, 0x80c04040,
 407 0x0040c040, 0x8040c040, 0x00c0c040, 0x80c0c040,
 408 0x004040c0, 0x804040c0, 0x00c040c0, 0x80c040c0,
 409 0x0040c0c0, 0x8040c0c0, 0x00c0c0c0, 0x80c0c0c0,
 410 0x40404040, 0xc0404040, 0x40c04040, 0xc0c04040,
 411 0x4040c040, 0xc040c040, 0x40c0c040, 0xc0c0c040,
 412 0x404040c0, 0xc04040c0, 0x40c040c0, 0xc0c040c0,
 413 0x4040c0c0, 0xc040c0c0, 0x40c0c0c0, 0xc0c0c0c0
 414 };
 415 
 416 static const uint64_t all_a = 0xaaaaaaaaaaaaaaaaULL;
 417 static const uint64_t all_5 = 0x5555555555555555ULL;
 418 static const uint64_t top_1 = 0xfc000000000000ULL;
 419 static const uint64_t mid_4 = 0x3fffffc000000ULL;
 420 static const uint64_t low_3 = 0x3ffff00ULL;
 421 
 422 
 423 static void
 424 des_ip(uint64_t *l, uint64_t *r, uint64_t pt)
 425 {
 426         uint64_t a, b;
 427 
 428         a = pt & all_a;
 429         b = pt & all_5;
 430         a = a | (a << 7);
 431         b = b | (b >> 7);
 432 
 433         b = (ip_table[0][(b >> 48) & 255ULL]) |
 434             (ip_table[1][(b >> 32) & 255ULL]) |
 435             (ip_table[0][(b >> 16) & 255ULL] << 6) |
 436             (ip_table[1][b & 255ULL] << 6);
 437 
 438         a = (ip_table[0][(a >> 56) & 255]) |
 439             (ip_table[1][(a >> 40) & 255]) |
 440             (ip_table[0][(a >> 24) & 255] << 6) |
 441             (ip_table[1][(a >> 8) & 255] << 6);
 442 
 443         *l = ((b & top_1) << 8) |
 444             (b & mid_4) |
 445             ((b & low_3) >> 5);
 446 
 447         *r = ((a & top_1) << 8) |
 448             (a & mid_4) |
 449             ((a & low_3) >> 5);
 450 }
 451 
 452 
 453 static uint64_t
 454 des_fp(uint64_t l, uint64_t r)
 455 {
 456         uint32_t upper, lower;
 457 
 458         lower = fp_table[((l >> 55) & 240) | ((r >> 59) & 15)] |
 459             (fp_table[((l >> 35) & 240) | ((r>>39) & 15)] >> 2) |
 460             (fp_table[((l >> 23) & 240) | ((r >> 27) & 15)] >> 4) |
 461             (fp_table[((l >> 6) & 240) | ((r >> 10) & 15)] >> 6);
 462 
 463         upper = fp_table[((l >> 41) & 240) | ((r >> 45) & 15)] |
 464             (fp_table[((l >> 29) & 240) | ((r >> 33) & 15)] >> 2) |
 465             (fp_table[((l >> 12) & 240) | ((r >> 16) & 15)] >> 4) |
 466             (fp_table[(l & 240) | (r >> 4) & 15] >> 6);
 467 
 468         return ((((uint64_t)upper) << 32) | (uint64_t)lower);
 469 
 470 }
 471 
 472 uint64_t
 473 des_crypt_impl(uint64_t *ks, uint64_t block, int one_or_three)
 474 {
 475         int i, j;
 476         uint64_t l, r, t;
 477 
 478         des_ip(&l, &r, block);
 479         for (j = 0; j < one_or_three; j++) {
 480                 for (i = j * 16; i < (j + 1) * 16; i++) {
 481                         t = r ^ ks[i];
 482                         t = sbox_table[0][t >> 58] |
 483                             sbox_table[1][(t >> 44) & 63] |
 484                             sbox_table[2][(t >> 38) & 63] |
 485                             sbox_table[3][(t >> 32) & 63] |
 486                             sbox_table[4][(t >> 26) & 63] |
 487                             sbox_table[5][(t >> 15) & 63] |
 488                             sbox_table[6][(t >> 9) & 63] |
 489                             sbox_table[7][(t >> 3) & 63];
 490                         t = t^l;
 491                         l = r;
 492                         r = t;
 493                 }
 494                 r = l;
 495                 l = t;
 496         }
 497 
 498         return (des_fp(l, r));
 499 }
 500 #endif /* !sun4u */
 501 
 502 int
 503 des3_crunch_block(const void *cookie, const uint8_t block[DES_BLOCK_LEN],
 504     uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt)
 505 {
 506         keysched3_t *ksch = (keysched3_t *)cookie;
 507 
 508         /*
 509          * The code below, that is always executed on LITTLE_ENDIAN machines,
 510          * reverses bytes in the block.  On BIG_ENDIAN, the same code
 511          * copies the block without reversing bytes.
 512          */
 513 #ifdef _BIG_ENDIAN
 514         if (IS_P2ALIGNED(block, sizeof (uint64_t)) &&
 515             IS_P2ALIGNED(out_block, sizeof (uint64_t))) {
 516                 if (decrypt == B_TRUE)
 517                         /* LINTED */
 518                         *(uint64_t *)out_block = des_crypt_impl(
 519                             ksch->ksch_decrypt, /* LINTED */
 520                             *(uint64_t *)block, 3);
 521                 else
 522                         /* LINTED */
 523                         *(uint64_t *)out_block = des_crypt_impl(
 524                             ksch->ksch_encrypt, /* LINTED */
 525                             *(uint64_t *)block, 3);
 526         } else
 527 #endif  /* _BIG_ENDIAN */
 528         {
 529                 uint64_t tmp;
 530 
 531 #ifdef UNALIGNED_POINTERS_PERMITTED
 532                 tmp = htonll(*(uint64_t *)(void *)&block[0]);
 533 #else
 534                 tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) |
 535                     ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) |
 536                     ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) |
 537                     ((uint64_t)block[6] << 8) | (uint64_t)block[7]);
 538 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 539 
 540                 if (decrypt == B_TRUE)
 541                         tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 3);
 542                 else
 543                         tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 3);
 544 
 545 #ifdef UNALIGNED_POINTERS_PERMITTED
 546                 *(uint64_t *)(void *)&out_block[0] = htonll(tmp);
 547 #else
 548                 out_block[0] = tmp >> 56;
 549                 out_block[1] = tmp >> 48;
 550                 out_block[2] = tmp >> 40;
 551                 out_block[3] = tmp >> 32;
 552                 out_block[4] = tmp >> 24;
 553                 out_block[5] = tmp >> 16;
 554                 out_block[6] = tmp >> 8;
 555                 out_block[7] = (uint8_t)tmp;
 556 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 557         }
 558         return (CRYPTO_SUCCESS);
 559 }
 560 
 561 int
 562 des_crunch_block(const void *cookie, const uint8_t block[DES_BLOCK_LEN],
 563     uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt)
 564 {
 565         keysched_t *ksch = (keysched_t *)cookie;
 566 
 567         /*
 568          * The code below, that is always executed on LITTLE_ENDIAN machines,
 569          * reverses bytes in the block.  On BIG_ENDIAN, the same code
 570          * copies the block without reversing bytes.
 571          */
 572 #ifdef _BIG_ENDIAN
 573         if (IS_P2ALIGNED(block, sizeof (uint64_t)) &&
 574             IS_P2ALIGNED(out_block, sizeof (uint64_t))) {
 575                 if (decrypt == B_TRUE)
 576                         /* LINTED */
 577                         *(uint64_t *)out_block = des_crypt_impl(
 578                             ksch->ksch_decrypt, /* LINTED */
 579                             *(uint64_t *)block, 1);
 580                 else
 581                         /* LINTED */
 582                         *(uint64_t *)out_block = des_crypt_impl(
 583                             ksch->ksch_encrypt, /* LINTED */
 584                             *(uint64_t *)block, 1);
 585 
 586         } else
 587 #endif  /* _BIG_ENDIAN */
 588         {
 589                 uint64_t tmp;
 590 
 591 #ifdef UNALIGNED_POINTERS_PERMITTED
 592                 tmp = htonll(*(uint64_t *)(void *)&block[0]);
 593 #else
 594                 tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) |
 595                     ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) |
 596                     ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) |
 597                     ((uint64_t)block[6] << 8) | (uint64_t)block[7]);
 598 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 599 
 600 
 601                 if (decrypt == B_TRUE)
 602                         tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 1);
 603                 else
 604                         tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 1);
 605 
 606 #ifdef UNALIGNED_POINTERS_PERMITTED
 607                 *(uint64_t *)(void *)&out_block[0] = htonll(tmp);
 608 #else
 609                 out_block[0] = tmp >> 56;
 610                 out_block[1] = tmp >> 48;
 611                 out_block[2] = tmp >> 40;
 612                 out_block[3] = tmp >> 32;
 613                 out_block[4] = tmp >> 24;
 614                 out_block[5] = tmp >> 16;
 615                 out_block[6] = tmp >> 8;
 616                 out_block[7] = (uint8_t)tmp;
 617 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 618         }
 619         return (CRYPTO_SUCCESS);
 620 }
 621 
 622 static boolean_t
 623 keycheck(uint8_t *key, uint8_t *corrected_key)
 624 {
 625         uint64_t key_so_far;
 626         uint_t i;
 627         /*
 628          * Table of weak and semi-weak keys.  Fortunately, weak keys are
 629          * endian-independent, and some semi-weak keys can be paired up in
 630          * endian-opposite order.  Since keys are stored as uint64_t's,
 631          * use the ifdef _LITTLE_ENDIAN where appropriate.
 632          */
 633         static uint64_t des_weak_keys[] = {
 634                 /* Really weak keys.  Byte-order independent values. */
 635                 0x0101010101010101ULL,
 636                 0x1f1f1f1f0e0e0e0eULL,
 637                 0xe0e0e0e0f1f1f1f1ULL,
 638                 0xfefefefefefefefeULL,
 639 
 640                 /* Semi-weak (and a few possibly-weak) keys. */
 641 
 642                 /* Byte-order independent semi-weak keys. */
 643                 0x01fe01fe01fe01feULL,  0xfe01fe01fe01fe01ULL,
 644 
 645                 /* Byte-order dependent semi-weak keys. */
 646 #ifdef _LITTLE_ENDIAN
 647                 0xf10ef10ee01fe01fULL,  0x0ef10ef11fe01fe0ULL,
 648                 0x01f101f101e001e0ULL,  0xf101f101e001e001ULL,
 649                 0x0efe0efe1ffe1ffeULL,  0xfe0efe0efe1ffe1fULL,
 650                 0x010e010e011f011fULL,  0x0e010e011f011f01ULL,
 651                 0xf1fef1fee0fee0feULL,  0xfef1fef1fee0fee0ULL,
 652 #else   /* Big endian */
 653                 0x1fe01fe00ef10ef1ULL,  0xe01fe01ff10ef10eULL,
 654                 0x01e001e001f101f1ULL,  0xe001e001f101f101ULL,
 655                 0x1ffe1ffe0efe0efeULL,  0xfe1ffe1ffe0efe0eULL,
 656                 0x011f011f010e010eULL,  0x1f011f010e010e01ULL,
 657                 0xe0fee0fef1fef1feULL,  0xfee0fee0fef1fef1ULL,
 658 #endif  /* _LITTLE_ENDIAN */
 659 
 660                 /* We'll save the other possibly-weak keys for the future. */
 661         };
 662 
 663         if (key == NULL)
 664                 return (B_FALSE);
 665 
 666 #ifdef UNALIGNED_POINTERS_PERMITTED
 667         key_so_far = htonll(*(uint64_t *)(void *)&key[0]);
 668 #else
 669         /*
 670          * The code below reverses the bytes on LITTLE_ENDIAN machines.
 671          * On BIG_ENDIAN, the same code copies without reversing
 672          * the bytes.
 673          */
 674         key_so_far = (((uint64_t)key[0] << 56) | ((uint64_t)key[1] << 48) |
 675             ((uint64_t)key[2] << 40) | ((uint64_t)key[3] << 32) |
 676             ((uint64_t)key[4] << 24) | ((uint64_t)key[5] << 16) |
 677             ((uint64_t)key[6] << 8) | (uint64_t)key[7]);
 678 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 679 
 680         /*
 681          * Fix parity.
 682          */
 683         fix_des_parity(&key_so_far);
 684 
 685         /* Do weak key check itself. */
 686         for (i = 0; i < (sizeof (des_weak_keys) / sizeof (uint64_t)); i++)
 687                 if (key_so_far == des_weak_keys[i]) {
 688                         return (B_FALSE);
 689                 }
 690 
 691         if (corrected_key != NULL) {
 692 #ifdef UNALIGNED_POINTERS_PERMITTED
 693                 *(uint64_t *)(void *)&corrected_key[0] = htonll(key_so_far);
 694 #else
 695                 /*
 696                  * The code below reverses the bytes on LITTLE_ENDIAN machines.
 697                  * On BIG_ENDIAN, the same code copies without reversing
 698                  * the bytes.
 699                  */
 700                 corrected_key[0] = key_so_far >> 56;
 701                 corrected_key[1] = key_so_far >> 48;
 702                 corrected_key[2] = key_so_far >> 40;
 703                 corrected_key[3] = key_so_far >> 32;
 704                 corrected_key[4] = key_so_far >> 24;
 705                 corrected_key[5] = key_so_far >> 16;
 706                 corrected_key[6] = key_so_far >> 8;
 707                 corrected_key[7] = (uint8_t)key_so_far;
 708 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 709         }
 710         return (B_TRUE);
 711 }
 712 
 713 static boolean_t
 714 des23_keycheck(uint8_t *key, uint8_t *corrected_key, boolean_t des3)
 715 {
 716         uint64_t aligned_key[DES3_KEYSIZE / sizeof (uint64_t)];
 717         uint64_t key_so_far, scratch, *currentkey;
 718         uint_t j, num_weakkeys = 0;
 719         uint8_t keysize = DES3_KEYSIZE;
 720         uint8_t checks = 3;
 721 
 722         if (key == NULL) {
 723                 return (B_FALSE);
 724         }
 725 
 726         if (des3 == B_FALSE) {
 727                 keysize = DES2_KEYSIZE;
 728                 checks = 2;
 729         }
 730 
 731         if (!IS_P2ALIGNED(key, sizeof (uint64_t))) {
 732                 bcopy(key, aligned_key, keysize);
 733                 currentkey = (uint64_t *)aligned_key;
 734         } else {
 735                 /* LINTED */
 736                 currentkey = (uint64_t *)key;
 737         }
 738 
 739         for (j = 0; j < checks; j++) {
 740                 key_so_far = currentkey[j];
 741 
 742                 if (!keycheck((uint8_t *)&key_so_far, (uint8_t *)&scratch)) {
 743                         if (++num_weakkeys > 1) {
 744                                 return (B_FALSE);
 745                         }
 746                         /*
 747                          * We found a weak key, but since
 748                          * we've only found one weak key,
 749                          * we can not reject the whole 3DES
 750                          * set of keys as weak.
 751                          *
 752                          * Break from the weak key loop
 753                          * (since this DES key is weak) and
 754                          * continue on.
 755                          */
 756                 }
 757 
 758                 currentkey[j] = scratch;
 759         }
 760 
 761         /*
 762          * Perform key equivalence checks, now that parity is properly set.
 763          * 1st and 2nd keys must be unique, the 3rd key can be the same as
 764          * the 1st key for the 2 key variant of 3DES.
 765          */
 766         if (currentkey[0] == currentkey[1] || currentkey[1] == currentkey[2])
 767                 return (B_FALSE);
 768 
 769         if (corrected_key != NULL) {
 770                 bcopy(currentkey, corrected_key, keysize);
 771         }
 772 
 773         return (B_TRUE);
 774 }
 775 
 776 boolean_t
 777 des_keycheck(uint8_t *key, des_strength_t strength, uint8_t *corrected_key)
 778 {
 779         if (strength == DES) {
 780                 return (keycheck(key, corrected_key));
 781         } else if (strength == DES2) {
 782                 return (des23_keycheck(key, corrected_key, B_FALSE));
 783         } else if (strength == DES3) {
 784                 return (des23_keycheck(key, corrected_key, B_TRUE));
 785         } else {
 786                 return (B_FALSE);
 787         }
 788 }
 789 
 790 void
 791 des_parity_fix(uint8_t *key, des_strength_t strength, uint8_t *corrected_key)
 792 {
 793         uint64_t aligned_key[DES3_KEYSIZE / sizeof (uint64_t)];
 794         uint8_t *paritied_key;
 795         uint64_t key_so_far;
 796         int i = 0, offset = 0;
 797 
 798         if (strength == DES)
 799                 bcopy(key, aligned_key, DES_KEYSIZE);
 800         else
 801                 bcopy(key, aligned_key, DES3_KEYSIZE);
 802 
 803         paritied_key = (uint8_t *)aligned_key;
 804         while (strength > i) {
 805                 offset = 8 * i;
 806 #ifdef UNALIGNED_POINTERS_PERMITTED
 807                 key_so_far = htonll(*(uint64_t *)(void *)&paritied_key[offset]);
 808 #else
 809                 key_so_far = (((uint64_t)paritied_key[offset + 0] << 56) |
 810                     ((uint64_t)paritied_key[offset + 1] << 48) |
 811                     ((uint64_t)paritied_key[offset + 2] << 40) |
 812                     ((uint64_t)paritied_key[offset + 3] << 32) |
 813                     ((uint64_t)paritied_key[offset + 4] << 24) |
 814                     ((uint64_t)paritied_key[offset + 5] << 16) |
 815                     ((uint64_t)paritied_key[offset + 6] << 8) |
 816                     (uint64_t)paritied_key[offset + 7]);
 817 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 818 
 819                 fix_des_parity(&key_so_far);
 820 
 821 #ifdef UNALIGNED_POINTERS_PERMITTED
 822                 *(uint64_t *)(void *)&paritied_key[offset] = htonll(key_so_far);
 823 #else
 824                 paritied_key[offset + 0] = key_so_far >> 56;
 825                 paritied_key[offset + 1] = key_so_far >> 48;
 826                 paritied_key[offset + 2] = key_so_far >> 40;
 827                 paritied_key[offset + 3] = key_so_far >> 32;
 828                 paritied_key[offset + 4] = key_so_far >> 24;
 829                 paritied_key[offset + 5] = key_so_far >> 16;
 830                 paritied_key[offset + 6] = key_so_far >> 8;
 831                 paritied_key[offset + 7] = (uint8_t)key_so_far;
 832 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 833 
 834                 i++;
 835         }
 836 
 837         bcopy(paritied_key, corrected_key, DES_KEYSIZE * strength);
 838 }
 839 
 840 
 841 /*
 842  * Initialize key schedule for DES, DES2, and DES3
 843  */
 844 void
 845 des_init_keysched(uint8_t *cipherKey, des_strength_t strength, void *ks)
 846 {
 847         uint64_t *encryption_ks;
 848         uint64_t *decryption_ks;
 849         uint64_t keysched[48];
 850         uint64_t key_uint64[3];
 851         uint64_t tmp;
 852         uint_t keysize, i, j;
 853 
 854         switch (strength) {
 855         case DES:
 856                 keysize = DES_KEYSIZE;
 857                 encryption_ks = ((keysched_t *)ks)->ksch_encrypt;
 858                 decryption_ks = ((keysched_t *)ks)->ksch_decrypt;
 859                 break;
 860         case DES2:
 861                 keysize = DES2_KEYSIZE;
 862                 encryption_ks = ((keysched3_t *)ks)->ksch_encrypt;
 863                 decryption_ks = ((keysched3_t *)ks)->ksch_decrypt;
 864                 break;
 865         case DES3:
 866                 keysize = DES3_KEYSIZE;
 867                 encryption_ks = ((keysched3_t *)ks)->ksch_encrypt;
 868                 decryption_ks = ((keysched3_t *)ks)->ksch_decrypt;
 869         }
 870 
 871         /*
 872          * The code below, that is always executed on LITTLE_ENDIAN machines,
 873          * reverses every 8 bytes in the key.  On BIG_ENDIAN, the same code
 874          * copies the key without reversing bytes.
 875          */
 876 #ifdef _BIG_ENDIAN
 877         if (IS_P2ALIGNED(cipherKey, sizeof (uint64_t))) {
 878                 for (i = 0, j = 0; j < keysize; i++, j += 8) {
 879                         /* LINTED: pointer alignment */
 880                         key_uint64[i] = *((uint64_t *)&cipherKey[j]);
 881                 }
 882         } else
 883 #endif  /* _BIG_ENDIAN */
 884         {
 885                 for (i = 0, j = 0; j < keysize; i++, j += 8) {
 886 #ifdef UNALIGNED_POINTERS_PERMITTED
 887                         key_uint64[i] =
 888                             htonll(*(uint64_t *)(void *)&cipherKey[j]);
 889 #else
 890                         key_uint64[i] = (((uint64_t)cipherKey[j] << 56) |
 891                             ((uint64_t)cipherKey[j + 1] << 48) |
 892                             ((uint64_t)cipherKey[j + 2] << 40) |
 893                             ((uint64_t)cipherKey[j + 3] << 32) |
 894                             ((uint64_t)cipherKey[j + 4] << 24) |
 895                             ((uint64_t)cipherKey[j + 5] << 16) |
 896                             ((uint64_t)cipherKey[j + 6] << 8) |
 897                             (uint64_t)cipherKey[j + 7]);
 898 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 899                 }
 900         }
 901 
 902         switch (strength) {
 903         case DES:
 904                 des_ks(keysched, key_uint64[0]);
 905                 break;
 906 
 907         case DES2:
 908                 /* DES2 is just DES3 with the first and third keys the same */
 909                 bcopy(key_uint64, key_uint64 + 2, DES_KEYSIZE);
 910                 /* FALLTHRU */
 911         case DES3:
 912                 des_ks(keysched, key_uint64[0]);
 913                 des_ks(keysched + 16, key_uint64[1]);
 914                 for (i = 0; i < 8; i++) {
 915                         tmp = keysched[16+i];
 916                         keysched[16+i] = keysched[31-i];
 917                         keysched[31-i] = tmp;
 918                 }
 919                 des_ks(keysched+32, key_uint64[2]);
 920                 keysize = DES3_KEYSIZE;
 921         }
 922 
 923         /* save the encryption keyschedule */
 924         bcopy(keysched, encryption_ks, keysize * 16);
 925 
 926         /* reverse the key schedule */
 927         for (i = 0; i < keysize; i++) {
 928                 tmp = keysched[i];
 929                 keysched[i] = keysched[2 * keysize - 1 - i];
 930                 keysched[2 * keysize -1 -i] = tmp;
 931         }
 932 
 933         /* save the decryption keyschedule */
 934         bcopy(keysched, decryption_ks, keysize * 16);
 935 }
 936 
 937 /*
 938  * Allocate key schedule.
 939  */
 940 /*ARGSUSED*/
 941 void *
 942 des_alloc_keysched(size_t *keysched_size, des_strength_t strength, int kmflag)
 943 {
 944         void *keysched;
 945 
 946         size_t size;
 947 
 948         switch (strength) {
 949         case DES:
 950                 size = sizeof (keysched_t);
 951                 break;
 952         case DES2:
 953         case DES3:
 954                 size = sizeof (keysched3_t);
 955         }
 956 
 957 #ifdef  _KERNEL
 958         keysched = (keysched_t *)kmem_alloc(size, kmflag);
 959 #else   /* !_KERNEL */
 960         keysched = (keysched_t *)malloc(size);
 961 #endif  /* _KERNEL */
 962 
 963         if (keysched == NULL)
 964                 return (NULL);
 965 
 966         if (keysched_size != NULL)
 967                 *keysched_size = size;
 968 
 969         return (keysched);
 970 }
 971 
 972 /*
 973  * Replace the LSB of each byte by the xor of the other
 974  * 7 bits.  The tricky thing is that the original contents of the LSBs
 975  * are nullified by including them twice in the xor computation.
 976  */
 977 static void
 978 fix_des_parity(uint64_t *keyp)
 979 {
 980         uint64_t k = *keyp;
 981         k ^= k >> 1;
 982         k ^= k >> 2;
 983         k ^= k >> 4;
 984         *keyp ^= (k & 0x0101010101010101ULL);
 985         *keyp ^= 0x0101010101010101ULL;
 986 }
 987 
 988 void
 989 des_copy_block(uint8_t *in, uint8_t *out)
 990 {
 991         if (IS_P2ALIGNED(in, sizeof (uint32_t)) &&
 992             IS_P2ALIGNED(out, sizeof (uint32_t))) {
 993                 /* LINTED: pointer alignment */
 994                 *(uint32_t *)&out[0] = *(uint32_t *)&in[0];
 995                 /* LINTED: pointer alignment */
 996                 *(uint32_t *)&out[4] = *(uint32_t *)&in[4];
 997         } else {
 998                 DES_COPY_BLOCK(in, out);
 999         }
1000 }
1001 
1002 /* XOR block of data into dest */
1003 void
1004 des_xor_block(uint8_t *data, uint8_t *dst)
1005 {
1006         if (IS_P2ALIGNED(dst, sizeof (uint32_t)) &&
1007             IS_P2ALIGNED(data, sizeof (uint32_t))) {
1008                 /* LINTED: pointer alignment */
1009                 *(uint32_t *)&dst[0] ^=
1010                     /* LINTED: pointer alignment */
1011                     *(uint32_t *)&data[0];
1012                     /* LINTED: pointer alignment */
1013                 *(uint32_t *)&dst[4] ^=
1014                     /* LINTED: pointer alignment */
1015                     *(uint32_t *)&data[4];
1016         } else {
1017                 DES_XOR_BLOCK(data, dst);
1018         }
1019 }
1020 
1021 int
1022 des_encrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
1023 {
1024         return (des_crunch_block(keysched, in, out, B_FALSE));
1025 }
1026 
1027 int
1028 des3_encrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
1029 {
1030         return (des3_crunch_block(keysched, in, out, B_FALSE));
1031 }
1032 
1033 int
1034 des_decrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
1035 {
1036         return (des_crunch_block(keysched, in, out, B_TRUE));
1037 }
1038 
1039 int
1040 des3_decrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
1041 {
1042         return (des3_crunch_block(keysched, in, out, B_TRUE));
1043 }
1044 
1045 /*
1046  * Encrypt multiple blocks of data according to mode.
1047  */
1048 int
1049 des_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
1050     crypto_data_t *out)
1051 {
1052         des_ctx_t *des_ctx = ctx;
1053         int rv;
1054 
1055         if (des_ctx->dc_flags & DES3_STRENGTH) {
1056                 if (des_ctx->dc_flags & CBC_MODE) {
1057                         rv = cbc_encrypt_contiguous_blocks(ctx, data,
1058                             length, out, DES_BLOCK_LEN, des3_encrypt_block,
1059                             des_copy_block, des_xor_block);
1060                 } else {
1061                         rv = ecb_cipher_contiguous_blocks(ctx, data, length,
1062                             out, DES_BLOCK_LEN, des3_encrypt_block);
1063                 }
1064         } else {
1065                 if (des_ctx->dc_flags & CBC_MODE) {
1066                         rv = cbc_encrypt_contiguous_blocks(ctx, data,
1067                             length, out, DES_BLOCK_LEN, des_encrypt_block,
1068                             des_copy_block, des_xor_block);
1069                 } else {
1070                         rv = ecb_cipher_contiguous_blocks(ctx, data, length,
1071                             out, DES_BLOCK_LEN, des_encrypt_block);
1072                 }
1073         }
1074         return (rv);
1075 }
1076 
1077 /*
1078  * Decrypt multiple blocks of data according to mode.
1079  */
1080 int
1081 des_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
1082     crypto_data_t *out)
1083 {
1084         des_ctx_t *des_ctx = ctx;
1085         int rv;
1086 
1087         if (des_ctx->dc_flags & DES3_STRENGTH) {
1088                 if (des_ctx->dc_flags & CBC_MODE) {
1089                         rv = cbc_decrypt_contiguous_blocks(ctx, data,
1090                             length, out, DES_BLOCK_LEN, des3_decrypt_block,
1091                             des_copy_block, des_xor_block);
1092                 } else {
1093                         rv = ecb_cipher_contiguous_blocks(ctx, data, length,
1094                             out, DES_BLOCK_LEN, des3_decrypt_block);
1095                         if (rv == CRYPTO_DATA_LEN_RANGE)
1096                                 rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
1097                 }
1098         } else {
1099                 if (des_ctx->dc_flags & CBC_MODE) {
1100                         rv = cbc_decrypt_contiguous_blocks(ctx, data,
1101                             length, out, DES_BLOCK_LEN, des_decrypt_block,
1102                             des_copy_block, des_xor_block);
1103                 } else {
1104                         rv = ecb_cipher_contiguous_blocks(ctx, data, length,
1105                             out, DES_BLOCK_LEN, des_decrypt_block);
1106                         if (rv == CRYPTO_DATA_LEN_RANGE)
1107                                 rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
1108                 }
1109         }
1110         return (rv);
1111 }