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