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