/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include #include #include #include "des_impl.h" #ifndef _KERNEL #include #include #endif /* !_KERNEL */ #if defined(__i386) || defined(__amd64) #include #define UNALIGNED_POINTERS_PERMITTED #endif typedef struct keysched_s { uint64_t ksch_encrypt[16]; uint64_t ksch_decrypt[16]; } keysched_t; typedef struct keysched3_s { uint64_t ksch_encrypt[48]; uint64_t ksch_decrypt[48]; } keysched3_t; static void fix_des_parity(uint64_t *); #ifndef sun4u static const uint64_t sbox_table[8][64]= { /* BEGIN CSTYLED */ { 0x0000140140020000ULL, 0x0000000000000000ULL, 0x0000000140000000ULL, 0x0000140140020020ULL, 0x0000140140000020ULL, 0x0000000140020020ULL, 0x0000000000000020ULL, 0x0000000140000000ULL, 0x0000000000020000ULL, 0x0000140140020000ULL, 0x0000140140020020ULL, 0x0000000000020000ULL, 0x0000140000020020ULL, 0x0000140140000020ULL, 0x0000140000000000ULL, 0x0000000000000020ULL, 0x0000000000020020ULL, 0x0000140000020000ULL, 0x0000140000020000ULL, 0x0000000140020000ULL, 0x0000000140020000ULL, 0x0000140140000000ULL, 0x0000140140000000ULL, 0x0000140000020020ULL, 0x0000000140000020ULL, 0x0000140000000020ULL, 0x0000140000000020ULL, 0x0000000140000020ULL, 0x0000000000000000ULL, 0x0000000000020020ULL, 0x0000000140020020ULL, 0x0000140000000000ULL, 0x0000000140000000ULL, 0x0000140140020020ULL, 0x0000000000000020ULL, 0x0000140140000000ULL, 0x0000140140020000ULL, 0x0000140000000000ULL, 0x0000140000000000ULL, 0x0000000000020000ULL, 0x0000140140000020ULL, 0x0000000140000000ULL, 0x0000000140020000ULL, 0x0000140000000020ULL, 0x0000000000020000ULL, 0x0000000000000020ULL, 0x0000140000020020ULL, 0x0000000140020020ULL, 0x0000140140020020ULL, 0x0000000140000020ULL, 0x0000140140000000ULL, 0x0000140000020020ULL, 0x0000140000000020ULL, 0x0000000000020020ULL, 0x0000000140020020ULL, 0x0000140140020000ULL, 0x0000000000020020ULL, 0x0000140000020000ULL, 0x0000140000020000ULL, 0x0000000000000000ULL, 0x0000000140000020ULL, 0x0000000140020000ULL, 0x0000000000000000ULL, 0x0000140140000020ULL }, { 0x2000005020000500ULL, 0x2000000020000000ULL, 0x0000000020000000ULL, 0x0000005020000500ULL, 0x0000005000000000ULL, 0x0000000000000500ULL, 0x2000005000000500ULL, 0x2000000020000500ULL, 0x2000000000000500ULL, 0x2000005020000500ULL, 0x2000005020000000ULL, 0x2000000000000000ULL, 0x2000000020000000ULL, 0x0000005000000000ULL, 0x0000000000000500ULL, 0x2000005000000500ULL, 0x0000005020000000ULL, 0x0000005000000500ULL, 0x2000000020000500ULL, 0x0000000000000000ULL, 0x2000000000000000ULL, 0x0000000020000000ULL, 0x0000005020000500ULL, 0x2000005000000000ULL, 0x0000005000000500ULL, 0x2000000000000500ULL, 0x0000000000000000ULL, 0x0000005020000000ULL, 0x0000000020000500ULL, 0x2000005020000000ULL, 0x2000005000000000ULL, 0x0000000020000500ULL, 0x0000000000000000ULL, 0x0000005020000500ULL, 0x2000005000000500ULL, 0x0000005000000000ULL, 0x2000000020000500ULL, 0x2000005000000000ULL, 0x2000005020000000ULL, 0x0000000020000000ULL, 0x2000005000000000ULL, 0x2000000020000000ULL, 0x0000000000000500ULL, 0x2000005020000500ULL, 0x0000005020000500ULL, 0x0000000000000500ULL, 0x0000000020000000ULL, 0x2000000000000000ULL, 0x0000000020000500ULL, 0x2000005020000000ULL, 0x0000005000000000ULL, 0x2000000000000500ULL, 0x0000005000000500ULL, 0x2000000020000500ULL, 0x2000000000000500ULL, 0x0000005000000500ULL, 0x0000005020000000ULL, 0x0000000000000000ULL, 0x2000000020000000ULL, 0x0000000020000500ULL, 0x2000000000000000ULL, 0x2000005000000500ULL, 0x2000005020000500ULL, 0x0000005020000000ULL }, { 0x0000000000014040ULL, 0x0000800280014000ULL, 0x0000000000000000ULL, 0x0000800280000040ULL, 0x0000800000014000ULL, 0x0000000000000000ULL, 0x0000000280014040ULL, 0x0000800000014000ULL, 0x0000000280000040ULL, 0x0000800000000040ULL, 0x0000800000000040ULL, 0x0000000280000000ULL, 0x0000800280014040ULL, 0x0000000280000040ULL, 0x0000800280000000ULL, 0x0000000000014040ULL, 0x0000800000000000ULL, 0x0000000000000040ULL, 0x0000800280014000ULL, 0x0000000000014000ULL, 0x0000000280014000ULL, 0x0000800280000000ULL, 0x0000800280000040ULL, 0x0000000280014040ULL, 0x0000800000014040ULL, 0x0000000280014000ULL, 0x0000000280000000ULL, 0x0000800000014040ULL, 0x0000000000000040ULL, 0x0000800280014040ULL, 0x0000000000014000ULL, 0x0000800000000000ULL, 0x0000800280014000ULL, 0x0000800000000000ULL, 0x0000000280000040ULL, 0x0000000000014040ULL, 0x0000000280000000ULL, 0x0000800280014000ULL, 0x0000800000014000ULL, 0x0000000000000000ULL, 0x0000000000014000ULL, 0x0000000280000040ULL, 0x0000800280014040ULL, 0x0000800000014000ULL, 0x0000800000000040ULL, 0x0000000000014000ULL, 0x0000000000000000ULL, 0x0000800280000040ULL, 0x0000800000014040ULL, 0x0000000280000000ULL, 0x0000800000000000ULL, 0x0000800280014040ULL, 0x0000000000000040ULL, 0x0000000280014040ULL, 0x0000000280014000ULL, 0x0000800000000040ULL, 0x0000800280000000ULL, 0x0000800000014040ULL, 0x0000000000014040ULL, 0x0000800280000000ULL, 0x0000000280014040ULL, 0x0000000000000040ULL, 0x0000800280000040ULL, 0x0000000280014000ULL }, { 0x4000020008100008ULL, 0x4000000008101008ULL, 0x4000000008101008ULL, 0x0000000000001000ULL, 0x0000020008101000ULL, 0x4000020000001008ULL, 0x4000020000000008ULL, 0x4000000008100008ULL, 0x0000000000000000ULL, 0x0000020008100000ULL, 0x0000020008100000ULL, 0x4000020008101008ULL, 0x4000000000001008ULL, 0x0000000000000000ULL, 0x0000020000001000ULL, 0x4000020000000008ULL, 0x4000000000000008ULL, 0x0000000008100000ULL, 0x0000020000000000ULL, 0x4000020008100008ULL, 0x0000000000001000ULL, 0x0000020000000000ULL, 0x4000000008100008ULL, 0x0000000008101000ULL, 0x4000020000001008ULL, 0x4000000000000008ULL, 0x0000000008101000ULL, 0x0000020000001000ULL, 0x0000000008100000ULL, 0x0000020008101000ULL, 0x4000020008101008ULL, 0x4000000000001008ULL, 0x0000020000001000ULL, 0x4000020000000008ULL, 0x0000020008100000ULL, 0x4000020008101008ULL, 0x4000000000001008ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000020008100000ULL, 0x0000000008101000ULL, 0x0000020000001000ULL, 0x4000020000001008ULL, 0x4000000000000008ULL, 0x4000020008100008ULL, 0x4000000008101008ULL, 0x4000000008101008ULL, 0x0000000000001000ULL, 0x4000020008101008ULL, 0x4000000000001008ULL, 0x4000000000000008ULL, 0x0000000008100000ULL, 0x4000020000000008ULL, 0x4000000008100008ULL, 0x0000020008101000ULL, 0x4000020000001008ULL, 0x4000000008100008ULL, 0x0000000008101000ULL, 0x0000020000000000ULL, 0x4000020008100008ULL, 0x0000000000001000ULL, 0x0000020000000000ULL, 0x0000000008100000ULL, 0x0000020008101000ULL }, { 0x000000000000a000ULL, 0x000028080000a000ULL, 0x0000280800000000ULL, 0x100028000000a000ULL, 0x0000000800000000ULL, 0x000000000000a000ULL, 0x1000000000000000ULL, 0x0000280800000000ULL, 0x100000080000a000ULL, 0x0000000800000000ULL, 0x000028000000a000ULL, 0x100000080000a000ULL, 0x100028000000a000ULL, 0x1000280800000000ULL, 0x000000080000a000ULL, 0x1000000000000000ULL, 0x0000280000000000ULL, 0x1000000800000000ULL, 0x1000000800000000ULL, 0x0000000000000000ULL, 0x100000000000a000ULL, 0x100028080000a000ULL, 0x100028080000a000ULL, 0x000028000000a000ULL, 0x1000280800000000ULL, 0x100000000000a000ULL, 0x0000000000000000ULL, 0x1000280000000000ULL, 0x000028080000a000ULL, 0x0000280000000000ULL, 0x1000280000000000ULL, 0x000000080000a000ULL, 0x0000000800000000ULL, 0x100028000000a000ULL, 0x000000000000a000ULL, 0x0000280000000000ULL, 0x1000000000000000ULL, 0x0000280800000000ULL, 0x100028000000a000ULL, 0x100000080000a000ULL, 0x000028000000a000ULL, 0x1000000000000000ULL, 0x1000280800000000ULL, 0x000028080000a000ULL, 0x100000080000a000ULL, 0x000000000000a000ULL, 0x0000280000000000ULL, 0x1000280800000000ULL, 0x100028080000a000ULL, 0x000000080000a000ULL, 0x1000280000000000ULL, 0x100028080000a000ULL, 0x0000280800000000ULL, 0x0000000000000000ULL, 0x1000000800000000ULL, 0x1000280000000000ULL, 0x000000080000a000ULL, 0x000028000000a000ULL, 0x100000000000a000ULL, 0x0000000800000000ULL, 0x0000000000000000ULL, 0x1000000800000000ULL, 0x000028080000a000ULL, 0x100000000000a000ULL }, { 0x0802000000000280ULL, 0x0802010000000000ULL, 0x0000000010000000ULL, 0x0802010010000280ULL, 0x0802010000000000ULL, 0x0000000000000280ULL, 0x0802010010000280ULL, 0x0000010000000000ULL, 0x0802000010000000ULL, 0x0000010010000280ULL, 0x0000010000000000ULL, 0x0802000000000280ULL, 0x0000010000000280ULL, 0x0802000010000000ULL, 0x0802000000000000ULL, 0x0000000010000280ULL, 0x0000000000000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL, 0x0000000010000000ULL, 0x0000010010000000ULL, 0x0802000010000280ULL, 0x0000000000000280ULL, 0x0802010000000280ULL, 0x0802010000000280ULL, 0x0000000000000000ULL, 0x0000010010000280ULL, 0x0802010010000000ULL, 0x0000000010000280ULL, 0x0000010010000000ULL, 0x0802010010000000ULL, 0x0802000000000000ULL, 0x0802000010000000ULL, 0x0000000000000280ULL, 0x0802010000000280ULL, 0x0000010010000000ULL, 0x0802010010000280ULL, 0x0000010000000000ULL, 0x0000000010000280ULL, 0x0802000000000280ULL, 0x0000010000000000ULL, 0x0802000010000000ULL, 0x0802000000000000ULL, 0x0000000010000280ULL, 0x0802000000000280ULL, 0x0802010010000280ULL, 0x0000010010000000ULL, 0x0802010000000000ULL, 0x0000010010000280ULL, 0x0802010010000000ULL, 0x0000000000000000ULL, 0x0802010000000280ULL, 0x0000000000000280ULL, 0x0000000010000000ULL, 0x0802010000000000ULL, 0x0000010010000280ULL, 0x0000000010000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL, 0x0000000000000000ULL, 0x0802010010000000ULL, 0x0802000000000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL }, { 0x000000a000000000ULL, 0x800040a000000010ULL, 0x8000400000040010ULL, 0x0000000000000000ULL, 0x0000000000040000ULL, 0x8000400000040010ULL, 0x800000a000040010ULL, 0x000040a000040000ULL, 0x800040a000040010ULL, 0x000000a000000000ULL, 0x0000000000000000ULL, 0x8000400000000010ULL, 0x8000000000000010ULL, 0x0000400000000000ULL, 0x800040a000000010ULL, 0x8000000000040010ULL, 0x0000400000040000ULL, 0x800000a000040010ULL, 0x800000a000000010ULL, 0x0000400000040000ULL, 0x8000400000000010ULL, 0x000040a000000000ULL, 0x000040a000040000ULL, 0x800000a000000010ULL, 0x000040a000000000ULL, 0x0000000000040000ULL, 0x8000000000040010ULL, 0x800040a000040010ULL, 0x000000a000040000ULL, 0x8000000000000010ULL, 0x0000400000000000ULL, 0x000000a000040000ULL, 0x0000400000000000ULL, 0x000000a000040000ULL, 0x000000a000000000ULL, 0x8000400000040010ULL, 0x8000400000040010ULL, 0x800040a000000010ULL, 0x800040a000000010ULL, 0x8000000000000010ULL, 0x800000a000000010ULL, 0x0000400000000000ULL, 0x0000400000040000ULL, 0x000000a000000000ULL, 0x000040a000040000ULL, 0x8000000000040010ULL, 0x800000a000040010ULL, 0x000040a000040000ULL, 0x8000000000040010ULL, 0x8000400000000010ULL, 0x800040a000040010ULL, 0x000040a000000000ULL, 0x000000a000040000ULL, 0x0000000000000000ULL, 0x8000000000000010ULL, 0x800040a000040010ULL, 0x0000000000000000ULL, 0x800000a000040010ULL, 0x000040a000000000ULL, 0x0000000000040000ULL, 0x8000400000000010ULL, 0x0000400000040000ULL, 0x0000000000040000ULL, 0x800000a000000010ULL }, { 0x0401000004080800ULL, 0x0000000004080000ULL, 0x0000000400000000ULL, 0x0401000404080800ULL, 0x0401000000000000ULL, 0x0401000004080800ULL, 0x0000000000000800ULL, 0x0401000000000000ULL, 0x0000000400000800ULL, 0x0401000400000000ULL, 0x0401000404080800ULL, 0x0000000404080000ULL, 0x0401000404080000ULL, 0x0000000404080800ULL, 0x0000000004080000ULL, 0x0000000000000800ULL, 0x0401000400000000ULL, 0x0401000000000800ULL, 0x0401000004080000ULL, 0x0000000004080800ULL, 0x0000000404080000ULL, 0x0000000400000800ULL, 0x0401000400000800ULL, 0x0401000404080000ULL, 0x0000000004080800ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0401000400000800ULL, 0x0401000000000800ULL, 0x0401000004080000ULL, 0x0000000404080800ULL, 0x0000000400000000ULL, 0x0000000404080800ULL, 0x0000000400000000ULL, 0x0401000404080000ULL, 0x0000000004080000ULL, 0x0000000000000800ULL, 0x0401000400000800ULL, 0x0000000004080000ULL, 0x0000000404080800ULL, 0x0401000004080000ULL, 0x0000000000000800ULL, 0x0401000000000800ULL, 0x0401000400000000ULL, 0x0401000400000800ULL, 0x0401000000000000ULL, 0x0000000400000000ULL, 0x0401000004080800ULL, 0x0000000000000000ULL, 0x0401000404080800ULL, 0x0000000400000800ULL, 0x0401000000000800ULL, 0x0401000400000000ULL, 0x0401000004080000ULL, 0x0401000004080800ULL, 0x0000000000000000ULL, 0x0401000404080800ULL, 0x0000000404080000ULL, 0x0000000404080000ULL, 0x0000000004080800ULL, 0x0000000004080800ULL, 0x0000000400000800ULL, 0x0401000000000000ULL, 0x0401000404080000ULL } /* END CSTYLED */ }; static const uint64_t ip_table[2][256]= { /* BEGIN CSTYLED */ { 0x0000000000000000ULL, 0x0000000000000400ULL, 0x0080000000000280ULL, 0x0080000000000680ULL, 0x0000000000400000ULL, 0x0000000000400400ULL, 0x0080000000400280ULL, 0x0080000000400680ULL, 0x0000000000280000ULL, 0x0000000000280400ULL, 0x0080000000280280ULL, 0x0080000000280680ULL, 0x0000000000680000ULL, 0x0000000000680400ULL, 0x0080000000680280ULL, 0x0080000000680680ULL, 0x0000000400000000ULL, 0x0000000400000400ULL, 0x0080000400000280ULL, 0x0080000400000680ULL, 0x0000000400400000ULL, 0x0000000400400400ULL, 0x0080000400400280ULL, 0x0080000400400680ULL, 0x0000000400280000ULL, 0x0000000400280400ULL, 0x0080000400280280ULL, 0x0080000400280680ULL, 0x0000000400680000ULL, 0x0000000400680400ULL, 0x0080000400680280ULL, 0x0080000400680680ULL, 0x0000000280000000ULL, 0x0000000280000400ULL, 0x0080000280000280ULL, 0x0080000280000680ULL, 0x0000000280400000ULL, 0x0000000280400400ULL, 0x0080000280400280ULL, 0x0080000280400680ULL, 0x0000000280280000ULL, 0x0000000280280400ULL, 0x0080000280280280ULL, 0x0080000280280680ULL, 0x0000000280680000ULL, 0x0000000280680400ULL, 0x0080000280680280ULL, 0x0080000280680680ULL, 0x0000000680000000ULL, 0x0000000680000400ULL, 0x0080000680000280ULL, 0x0080000680000680ULL, 0x0000000680400000ULL, 0x0000000680400400ULL, 0x0080000680400280ULL, 0x0080000680400680ULL, 0x0000000680280000ULL, 0x0000000680280400ULL, 0x0080000680280280ULL, 0x0080000680280680ULL, 0x0000000680680000ULL, 0x0000000680680400ULL, 0x0080000680680280ULL, 0x0080000680680680ULL, 0x0000400000000000ULL, 0x0000400000000400ULL, 0x0080400000000280ULL, 0x0080400000000680ULL, 0x0000400000400000ULL, 0x0000400000400400ULL, 0x0080400000400280ULL, 0x0080400000400680ULL, 0x0000400000280000ULL, 0x0000400000280400ULL, 0x0080400000280280ULL, 0x0080400000280680ULL, 0x0000400000680000ULL, 0x0000400000680400ULL, 0x0080400000680280ULL, 0x0080400000680680ULL, 0x0000400400000000ULL, 0x0000400400000400ULL, 0x0080400400000280ULL, 0x0080400400000680ULL, 0x0000400400400000ULL, 0x0000400400400400ULL, 0x0080400400400280ULL, 0x0080400400400680ULL, 0x0000400400280000ULL, 0x0000400400280400ULL, 0x0080400400280280ULL, 0x0080400400280680ULL, 0x0000400400680000ULL, 0x0000400400680400ULL, 0x0080400400680280ULL, 0x0080400400680680ULL, 0x0000400280000000ULL, 0x0000400280000400ULL, 0x0080400280000280ULL, 0x0080400280000680ULL, 0x0000400280400000ULL, 0x0000400280400400ULL, 0x0080400280400280ULL, 0x0080400280400680ULL, 0x0000400280280000ULL, 0x0000400280280400ULL, 0x0080400280280280ULL, 0x0080400280280680ULL, 0x0000400280680000ULL, 0x0000400280680400ULL, 0x0080400280680280ULL, 0x0080400280680680ULL, 0x0000400680000000ULL, 0x0000400680000400ULL, 0x0080400680000280ULL, 0x0080400680000680ULL, 0x0000400680400000ULL, 0x0000400680400400ULL, 0x0080400680400280ULL, 0x0080400680400680ULL, 0x0000400680280000ULL, 0x0000400680280400ULL, 0x0080400680280280ULL, 0x0080400680280680ULL, 0x0000400680680000ULL, 0x0000400680680400ULL, 0x0080400680680280ULL, 0x0080400680680680ULL, 0x0000280000000000ULL, 0x0000280000000400ULL, 0x0080280000000280ULL, 0x0080280000000680ULL, 0x0000280000400000ULL, 0x0000280000400400ULL, 0x0080280000400280ULL, 0x0080280000400680ULL, 0x0000280000280000ULL, 0x0000280000280400ULL, 0x0080280000280280ULL, 0x0080280000280680ULL, 0x0000280000680000ULL, 0x0000280000680400ULL, 0x0080280000680280ULL, 0x0080280000680680ULL, 0x0000280400000000ULL, 0x0000280400000400ULL, 0x0080280400000280ULL, 0x0080280400000680ULL, 0x0000280400400000ULL, 0x0000280400400400ULL, 0x0080280400400280ULL, 0x0080280400400680ULL, 0x0000280400280000ULL, 0x0000280400280400ULL, 0x0080280400280280ULL, 0x0080280400280680ULL, 0x0000280400680000ULL, 0x0000280400680400ULL, 0x0080280400680280ULL, 0x0080280400680680ULL, 0x0000280280000000ULL, 0x0000280280000400ULL, 0x0080280280000280ULL, 0x0080280280000680ULL, 0x0000280280400000ULL, 0x0000280280400400ULL, 0x0080280280400280ULL, 0x0080280280400680ULL, 0x0000280280280000ULL, 0x0000280280280400ULL, 0x0080280280280280ULL, 0x0080280280280680ULL, 0x0000280280680000ULL, 0x0000280280680400ULL, 0x0080280280680280ULL, 0x0080280280680680ULL, 0x0000280680000000ULL, 0x0000280680000400ULL, 0x0080280680000280ULL, 0x0080280680000680ULL, 0x0000280680400000ULL, 0x0000280680400400ULL, 0x0080280680400280ULL, 0x0080280680400680ULL, 0x0000280680280000ULL, 0x0000280680280400ULL, 0x0080280680280280ULL, 0x0080280680280680ULL, 0x0000280680680000ULL, 0x0000280680680400ULL, 0x0080280680680280ULL, 0x0080280680680680ULL, 0x0000680000000000ULL, 0x0000680000000400ULL, 0x0080680000000280ULL, 0x0080680000000680ULL, 0x0000680000400000ULL, 0x0000680000400400ULL, 0x0080680000400280ULL, 0x0080680000400680ULL, 0x0000680000280000ULL, 0x0000680000280400ULL, 0x0080680000280280ULL, 0x0080680000280680ULL, 0x0000680000680000ULL, 0x0000680000680400ULL, 0x0080680000680280ULL, 0x0080680000680680ULL, 0x0000680400000000ULL, 0x0000680400000400ULL, 0x0080680400000280ULL, 0x0080680400000680ULL, 0x0000680400400000ULL, 0x0000680400400400ULL, 0x0080680400400280ULL, 0x0080680400400680ULL, 0x0000680400280000ULL, 0x0000680400280400ULL, 0x0080680400280280ULL, 0x0080680400280680ULL, 0x0000680400680000ULL, 0x0000680400680400ULL, 0x0080680400680280ULL, 0x0080680400680680ULL, 0x0000680280000000ULL, 0x0000680280000400ULL, 0x0080680280000280ULL, 0x0080680280000680ULL, 0x0000680280400000ULL, 0x0000680280400400ULL, 0x0080680280400280ULL, 0x0080680280400680ULL, 0x0000680280280000ULL, 0x0000680280280400ULL, 0x0080680280280280ULL, 0x0080680280280680ULL, 0x0000680280680000ULL, 0x0000680280680400ULL, 0x0080680280680280ULL, 0x0080680280680680ULL, 0x0000680680000000ULL, 0x0000680680000400ULL, 0x0080680680000280ULL, 0x0080680680000680ULL, 0x0000680680400000ULL, 0x0000680680400400ULL, 0x0080680680400280ULL, 0x0080680680400680ULL, 0x0000680680280000ULL, 0x0000680680280400ULL, 0x0080680680280280ULL, 0x0080680680280680ULL, 0x0000680680680000ULL, 0x0000680680680400ULL, 0x0080680680680280ULL, 0x0080680680680680ULL }, { 0x0000000000000000ULL, 0x0000000000005000ULL, 0x0000000000000800ULL, 0x0000000000005800ULL, 0x0000000005000000ULL, 0x0000000005005000ULL, 0x0000000005000800ULL, 0x0000000005005800ULL, 0x0000000000800000ULL, 0x0000000000805000ULL, 0x0000000000800800ULL, 0x0000000000805800ULL, 0x0000000005800000ULL, 0x0000000005805000ULL, 0x0000000005800800ULL, 0x0000000005805800ULL, 0x0000005000000000ULL, 0x0000005000005000ULL, 0x0000005000000800ULL, 0x0000005000005800ULL, 0x0000005005000000ULL, 0x0000005005005000ULL, 0x0000005005000800ULL, 0x0000005005005800ULL, 0x0000005000800000ULL, 0x0000005000805000ULL, 0x0000005000800800ULL, 0x0000005000805800ULL, 0x0000005005800000ULL, 0x0000005005805000ULL, 0x0000005005800800ULL, 0x0000005005805800ULL, 0x0000000800000000ULL, 0x0000000800005000ULL, 0x0000000800000800ULL, 0x0000000800005800ULL, 0x0000000805000000ULL, 0x0000000805005000ULL, 0x0000000805000800ULL, 0x0000000805005800ULL, 0x0000000800800000ULL, 0x0000000800805000ULL, 0x0000000800800800ULL, 0x0000000800805800ULL, 0x0000000805800000ULL, 0x0000000805805000ULL, 0x0000000805800800ULL, 0x0000000805805800ULL, 0x0000005800000000ULL, 0x0000005800005000ULL, 0x0000005800000800ULL, 0x0000005800005800ULL, 0x0000005805000000ULL, 0x0000005805005000ULL, 0x0000005805000800ULL, 0x0000005805005800ULL, 0x0000005800800000ULL, 0x0000005800805000ULL, 0x0000005800800800ULL, 0x0000005800805800ULL, 0x0000005805800000ULL, 0x0000005805805000ULL, 0x0000005805800800ULL, 0x0000005805805800ULL, 0x0005000000000004ULL, 0x0005000000005004ULL, 0x0005000000000804ULL, 0x0005000000005804ULL, 0x0005000005000004ULL, 0x0005000005005004ULL, 0x0005000005000804ULL, 0x0005000005005804ULL, 0x0005000000800004ULL, 0x0005000000805004ULL, 0x0005000000800804ULL, 0x0005000000805804ULL, 0x0005000005800004ULL, 0x0005000005805004ULL, 0x0005000005800804ULL, 0x0005000005805804ULL, 0x0005005000000004ULL, 0x0005005000005004ULL, 0x0005005000000804ULL, 0x0005005000005804ULL, 0x0005005005000004ULL, 0x0005005005005004ULL, 0x0005005005000804ULL, 0x0005005005005804ULL, 0x0005005000800004ULL, 0x0005005000805004ULL, 0x0005005000800804ULL, 0x0005005000805804ULL, 0x0005005005800004ULL, 0x0005005005805004ULL, 0x0005005005800804ULL, 0x0005005005805804ULL, 0x0005000800000004ULL, 0x0005000800005004ULL, 0x0005000800000804ULL, 0x0005000800005804ULL, 0x0005000805000004ULL, 0x0005000805005004ULL, 0x0005000805000804ULL, 0x0005000805005804ULL, 0x0005000800800004ULL, 0x0005000800805004ULL, 0x0005000800800804ULL, 0x0005000800805804ULL, 0x0005000805800004ULL, 0x0005000805805004ULL, 0x0005000805800804ULL, 0x0005000805805804ULL, 0x0005005800000004ULL, 0x0005005800005004ULL, 0x0005005800000804ULL, 0x0005005800005804ULL, 0x0005005805000004ULL, 0x0005005805005004ULL, 0x0005005805000804ULL, 0x0005005805005804ULL, 0x0005005800800004ULL, 0x0005005800805004ULL, 0x0005005800800804ULL, 0x0005005800805804ULL, 0x0005005805800004ULL, 0x0005005805805004ULL, 0x0005005805800804ULL, 0x0005005805805804ULL, 0x0000800000000000ULL, 0x0000800000005000ULL, 0x0000800000000800ULL, 0x0000800000005800ULL, 0x0000800005000000ULL, 0x0000800005005000ULL, 0x0000800005000800ULL, 0x0000800005005800ULL, 0x0000800000800000ULL, 0x0000800000805000ULL, 0x0000800000800800ULL, 0x0000800000805800ULL, 0x0000800005800000ULL, 0x0000800005805000ULL, 0x0000800005800800ULL, 0x0000800005805800ULL, 0x0000805000000000ULL, 0x0000805000005000ULL, 0x0000805000000800ULL, 0x0000805000005800ULL, 0x0000805005000000ULL, 0x0000805005005000ULL, 0x0000805005000800ULL, 0x0000805005005800ULL, 0x0000805000800000ULL, 0x0000805000805000ULL, 0x0000805000800800ULL, 0x0000805000805800ULL, 0x0000805005800000ULL, 0x0000805005805000ULL, 0x0000805005800800ULL, 0x0000805005805800ULL, 0x0000800800000000ULL, 0x0000800800005000ULL, 0x0000800800000800ULL, 0x0000800800005800ULL, 0x0000800805000000ULL, 0x0000800805005000ULL, 0x0000800805000800ULL, 0x0000800805005800ULL, 0x0000800800800000ULL, 0x0000800800805000ULL, 0x0000800800800800ULL, 0x0000800800805800ULL, 0x0000800805800000ULL, 0x0000800805805000ULL, 0x0000800805800800ULL, 0x0000800805805800ULL, 0x0000805800000000ULL, 0x0000805800005000ULL, 0x0000805800000800ULL, 0x0000805800005800ULL, 0x0000805805000000ULL, 0x0000805805005000ULL, 0x0000805805000800ULL, 0x0000805805005800ULL, 0x0000805800800000ULL, 0x0000805800805000ULL, 0x0000805800800800ULL, 0x0000805800805800ULL, 0x0000805805800000ULL, 0x0000805805805000ULL, 0x0000805805800800ULL, 0x0000805805805800ULL, 0x0005800000000004ULL, 0x0005800000005004ULL, 0x0005800000000804ULL, 0x0005800000005804ULL, 0x0005800005000004ULL, 0x0005800005005004ULL, 0x0005800005000804ULL, 0x0005800005005804ULL, 0x0005800000800004ULL, 0x0005800000805004ULL, 0x0005800000800804ULL, 0x0005800000805804ULL, 0x0005800005800004ULL, 0x0005800005805004ULL, 0x0005800005800804ULL, 0x0005800005805804ULL, 0x0005805000000004ULL, 0x0005805000005004ULL, 0x0005805000000804ULL, 0x0005805000005804ULL, 0x0005805005000004ULL, 0x0005805005005004ULL, 0x0005805005000804ULL, 0x0005805005005804ULL, 0x0005805000800004ULL, 0x0005805000805004ULL, 0x0005805000800804ULL, 0x0005805000805804ULL, 0x0005805005800004ULL, 0x0005805005805004ULL, 0x0005805005800804ULL, 0x0005805005805804ULL, 0x0005800800000004ULL, 0x0005800800005004ULL, 0x0005800800000804ULL, 0x0005800800005804ULL, 0x0005800805000004ULL, 0x0005800805005004ULL, 0x0005800805000804ULL, 0x0005800805005804ULL, 0x0005800800800004ULL, 0x0005800800805004ULL, 0x0005800800800804ULL, 0x0005800800805804ULL, 0x0005800805800004ULL, 0x0005800805805004ULL, 0x0005800805800804ULL, 0x0005800805805804ULL, 0x0005805800000004ULL, 0x0005805800005004ULL, 0x0005805800000804ULL, 0x0005805800005804ULL, 0x0005805805000004ULL, 0x0005805805005004ULL, 0x0005805805000804ULL, 0x0005805805005804ULL, 0x0005805800800004ULL, 0x0005805800805004ULL, 0x0005805800800804ULL, 0x0005805800805804ULL, 0x0005805805800004ULL, 0x0005805805805004ULL, 0x0005805805800804ULL, 0x0005805805805804ULL } /* END CSTYLED */ }; static const uint32_t fp_table[256]= { 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, 0x80808080, 0x40000000, 0xc0000000, 0x40800000, 0xc0800000, 0x40008000, 0xc0008000, 0x40808000, 0xc0808000, 0x40000080, 0xc0000080, 0x40800080, 0xc0800080, 0x40008080, 0xc0008080, 0x40808080, 0xc0808080, 0x00400000, 0x80400000, 0x00c00000, 0x80c00000, 0x00408000, 0x80408000, 0x00c08000, 0x80c08000, 0x00400080, 0x80400080, 0x00c00080, 0x80c00080, 0x00408080, 0x80408080, 0x00c08080, 0x80c08080, 0x40400000, 0xc0400000, 0x40c00000, 0xc0c00000, 0x40408000, 0xc0408000, 0x40c08000, 0xc0c08000, 0x40400080, 0xc0400080, 0x40c00080, 0xc0c00080, 0x40408080, 0xc0408080, 0x40c08080, 0xc0c08080, 0x00004000, 0x80004000, 0x00804000, 0x80804000, 0x0000c000, 0x8000c000, 0x0080c000, 0x8080c000, 0x00004080, 0x80004080, 0x00804080, 0x80804080, 0x0000c080, 0x8000c080, 0x0080c080, 0x8080c080, 0x40004000, 0xc0004000, 0x40804000, 0xc0804000, 0x4000c000, 0xc000c000, 0x4080c000, 0xc080c000, 0x40004080, 0xc0004080, 0x40804080, 0xc0804080, 0x4000c080, 0xc000c080, 0x4080c080, 0xc080c080, 0x00404000, 0x80404000, 0x00c04000, 0x80c04000, 0x0040c000, 0x8040c000, 0x00c0c000, 0x80c0c000, 0x00404080, 0x80404080, 0x00c04080, 0x80c04080, 0x0040c080, 0x8040c080, 0x00c0c080, 0x80c0c080, 0x40404000, 0xc0404000, 0x40c04000, 0xc0c04000, 0x4040c000, 0xc040c000, 0x40c0c000, 0xc0c0c000, 0x40404080, 0xc0404080, 0x40c04080, 0xc0c04080, 0x4040c080, 0xc040c080, 0x40c0c080, 0xc0c0c080, 0x00000040, 0x80000040, 0x00800040, 0x80800040, 0x00008040, 0x80008040, 0x00808040, 0x80808040, 0x000000c0, 0x800000c0, 0x008000c0, 0x808000c0, 0x000080c0, 0x800080c0, 0x008080c0, 0x808080c0, 0x40000040, 0xc0000040, 0x40800040, 0xc0800040, 0x40008040, 0xc0008040, 0x40808040, 0xc0808040, 0x400000c0, 0xc00000c0, 0x408000c0, 0xc08000c0, 0x400080c0, 0xc00080c0, 0x408080c0, 0xc08080c0, 0x00400040, 0x80400040, 0x00c00040, 0x80c00040, 0x00408040, 0x80408040, 0x00c08040, 0x80c08040, 0x004000c0, 0x804000c0, 0x00c000c0, 0x80c000c0, 0x004080c0, 0x804080c0, 0x00c080c0, 0x80c080c0, 0x40400040, 0xc0400040, 0x40c00040, 0xc0c00040, 0x40408040, 0xc0408040, 0x40c08040, 0xc0c08040, 0x404000c0, 0xc04000c0, 0x40c000c0, 0xc0c000c0, 0x404080c0, 0xc04080c0, 0x40c080c0, 0xc0c080c0, 0x00004040, 0x80004040, 0x00804040, 0x80804040, 0x0000c040, 0x8000c040, 0x0080c040, 0x8080c040, 0x000040c0, 0x800040c0, 0x008040c0, 0x808040c0, 0x0000c0c0, 0x8000c0c0, 0x0080c0c0, 0x8080c0c0, 0x40004040, 0xc0004040, 0x40804040, 0xc0804040, 0x4000c040, 0xc000c040, 0x4080c040, 0xc080c040, 0x400040c0, 0xc00040c0, 0x408040c0, 0xc08040c0, 0x4000c0c0, 0xc000c0c0, 0x4080c0c0, 0xc080c0c0, 0x00404040, 0x80404040, 0x00c04040, 0x80c04040, 0x0040c040, 0x8040c040, 0x00c0c040, 0x80c0c040, 0x004040c0, 0x804040c0, 0x00c040c0, 0x80c040c0, 0x0040c0c0, 0x8040c0c0, 0x00c0c0c0, 0x80c0c0c0, 0x40404040, 0xc0404040, 0x40c04040, 0xc0c04040, 0x4040c040, 0xc040c040, 0x40c0c040, 0xc0c0c040, 0x404040c0, 0xc04040c0, 0x40c040c0, 0xc0c040c0, 0x4040c0c0, 0xc040c0c0, 0x40c0c0c0, 0xc0c0c0c0 }; static const uint64_t all_a = 0xaaaaaaaaaaaaaaaaULL; static const uint64_t all_5 = 0x5555555555555555ULL; static const uint64_t top_1 = 0xfc000000000000ULL; static const uint64_t mid_4 = 0x3fffffc000000ULL; static const uint64_t low_3 = 0x3ffff00ULL; static void des_ip(uint64_t *l, uint64_t *r, uint64_t pt) { uint64_t a, b; a = pt & all_a; b = pt & all_5; a = a | (a << 7); b = b | (b >> 7); b = (ip_table[0][(b >> 48) & 255ULL]) | (ip_table[1][(b >> 32) & 255ULL]) | (ip_table[0][(b >> 16) & 255ULL] << 6) | (ip_table[1][b & 255ULL] << 6); a = (ip_table[0][(a >> 56) & 255]) | (ip_table[1][(a >> 40) & 255]) | (ip_table[0][(a >> 24) & 255] << 6) | (ip_table[1][(a >> 8) & 255] << 6); *l = ((b & top_1) << 8) | (b & mid_4) | ((b & low_3) >> 5); *r = ((a & top_1) << 8) | (a & mid_4) | ((a & low_3) >> 5); } static uint64_t des_fp(uint64_t l, uint64_t r) { uint32_t upper, lower; lower = fp_table[((l >> 55) & 240) | ((r >> 59) & 15)] | (fp_table[((l >> 35) & 240) | ((r>>39) & 15)] >> 2) | (fp_table[((l >> 23) & 240) | ((r >> 27) & 15)] >> 4) | (fp_table[((l >> 6) & 240) | ((r >> 10) & 15)] >> 6); upper = fp_table[((l >> 41) & 240) | ((r >> 45) & 15)] | (fp_table[((l >> 29) & 240) | ((r >> 33) & 15)] >> 2) | (fp_table[((l >> 12) & 240) | ((r >> 16) & 15)] >> 4) | (fp_table[(l & 240) | (r >> 4) & 15] >> 6); return ((((uint64_t)upper) << 32) | (uint64_t)lower); } uint64_t des_crypt_impl(uint64_t *ks, uint64_t block, int one_or_three) { int i, j; uint64_t l, r, t; des_ip(&l, &r, block); for (j = 0; j < one_or_three; j++) { for (i = j * 16; i < (j + 1) * 16; i++) { t = r ^ ks[i]; t = sbox_table[0][t >> 58] | sbox_table[1][(t >> 44) & 63] | sbox_table[2][(t >> 38) & 63] | sbox_table[3][(t >> 32) & 63] | sbox_table[4][(t >> 26) & 63] | sbox_table[5][(t >> 15) & 63] | sbox_table[6][(t >> 9) & 63] | sbox_table[7][(t >> 3) & 63]; t = t^l; l = r; r = t; } r = l; l = t; } return (des_fp(l, r)); } #endif /* !sun4u */ int des3_crunch_block(const void *cookie, const uint8_t block[DES_BLOCK_LEN], uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt) { keysched3_t *ksch = (keysched3_t *)cookie; /* * The code below, that is always executed on LITTLE_ENDIAN machines, * reverses bytes in the block. On BIG_ENDIAN, the same code * copies the block without reversing bytes. */ #ifdef _BIG_ENDIAN if (IS_P2ALIGNED(block, sizeof (uint64_t)) && IS_P2ALIGNED(out_block, sizeof (uint64_t))) { if (decrypt == B_TRUE) /* LINTED */ *(uint64_t *)out_block = des_crypt_impl( ksch->ksch_decrypt, /* LINTED */ *(uint64_t *)block, 3); else /* LINTED */ *(uint64_t *)out_block = des_crypt_impl( ksch->ksch_encrypt, /* LINTED */ *(uint64_t *)block, 3); } else #endif /* _BIG_ENDIAN */ { uint64_t tmp; #ifdef UNALIGNED_POINTERS_PERMITTED tmp = htonll(*(uint64_t *)(void *)&block[0]); #else tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) | ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) | ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) | ((uint64_t)block[6] << 8) | (uint64_t)block[7]); #endif /* UNALIGNED_POINTERS_PERMITTED */ if (decrypt == B_TRUE) tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 3); else tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 3); #ifdef UNALIGNED_POINTERS_PERMITTED *(uint64_t *)(void *)&out_block[0] = htonll(tmp); #else out_block[0] = tmp >> 56; out_block[1] = tmp >> 48; out_block[2] = tmp >> 40; out_block[3] = tmp >> 32; out_block[4] = tmp >> 24; out_block[5] = tmp >> 16; out_block[6] = tmp >> 8; out_block[7] = (uint8_t)tmp; #endif /* UNALIGNED_POINTERS_PERMITTED */ } return (CRYPTO_SUCCESS); } int des_crunch_block(const void *cookie, const uint8_t block[DES_BLOCK_LEN], uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt) { keysched_t *ksch = (keysched_t *)cookie; /* * The code below, that is always executed on LITTLE_ENDIAN machines, * reverses bytes in the block. On BIG_ENDIAN, the same code * copies the block without reversing bytes. */ #ifdef _BIG_ENDIAN if (IS_P2ALIGNED(block, sizeof (uint64_t)) && IS_P2ALIGNED(out_block, sizeof (uint64_t))) { if (decrypt == B_TRUE) /* LINTED */ *(uint64_t *)out_block = des_crypt_impl( ksch->ksch_decrypt, /* LINTED */ *(uint64_t *)block, 1); else /* LINTED */ *(uint64_t *)out_block = des_crypt_impl( ksch->ksch_encrypt, /* LINTED */ *(uint64_t *)block, 1); } else #endif /* _BIG_ENDIAN */ { uint64_t tmp; #ifdef UNALIGNED_POINTERS_PERMITTED tmp = htonll(*(uint64_t *)(void *)&block[0]); #else tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) | ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) | ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) | ((uint64_t)block[6] << 8) | (uint64_t)block[7]); #endif /* UNALIGNED_POINTERS_PERMITTED */ if (decrypt == B_TRUE) tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 1); else tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 1); #ifdef UNALIGNED_POINTERS_PERMITTED *(uint64_t *)(void *)&out_block[0] = htonll(tmp); #else out_block[0] = tmp >> 56; out_block[1] = tmp >> 48; out_block[2] = tmp >> 40; out_block[3] = tmp >> 32; out_block[4] = tmp >> 24; out_block[5] = tmp >> 16; out_block[6] = tmp >> 8; out_block[7] = (uint8_t)tmp; #endif /* UNALIGNED_POINTERS_PERMITTED */ } return (CRYPTO_SUCCESS); } static boolean_t keycheck(uint8_t *key, uint8_t *corrected_key) { uint64_t key_so_far; uint_t i; /* * Table of weak and semi-weak keys. Fortunately, weak keys are * endian-independent, and some semi-weak keys can be paired up in * endian-opposite order. Since keys are stored as uint64_t's, * use the ifdef _LITTLE_ENDIAN where appropriate. */ static uint64_t des_weak_keys[] = { /* Really weak keys. Byte-order independent values. */ 0x0101010101010101ULL, 0x1f1f1f1f0e0e0e0eULL, 0xe0e0e0e0f1f1f1f1ULL, 0xfefefefefefefefeULL, /* Semi-weak (and a few possibly-weak) keys. */ /* Byte-order independent semi-weak keys. */ 0x01fe01fe01fe01feULL, 0xfe01fe01fe01fe01ULL, /* Byte-order dependent semi-weak keys. */ #ifdef _LITTLE_ENDIAN 0xf10ef10ee01fe01fULL, 0x0ef10ef11fe01fe0ULL, 0x01f101f101e001e0ULL, 0xf101f101e001e001ULL, 0x0efe0efe1ffe1ffeULL, 0xfe0efe0efe1ffe1fULL, 0x010e010e011f011fULL, 0x0e010e011f011f01ULL, 0xf1fef1fee0fee0feULL, 0xfef1fef1fee0fee0ULL, #else /* Big endian */ 0x1fe01fe00ef10ef1ULL, 0xe01fe01ff10ef10eULL, 0x01e001e001f101f1ULL, 0xe001e001f101f101ULL, 0x1ffe1ffe0efe0efeULL, 0xfe1ffe1ffe0efe0eULL, 0x011f011f010e010eULL, 0x1f011f010e010e01ULL, 0xe0fee0fef1fef1feULL, 0xfee0fee0fef1fef1ULL, #endif /* _LITTLE_ENDIAN */ /* We'll save the other possibly-weak keys for the future. */ }; if (key == NULL) return (B_FALSE); #ifdef UNALIGNED_POINTERS_PERMITTED key_so_far = htonll(*(uint64_t *)(void *)&key[0]); #else /* * The code below reverses the bytes on LITTLE_ENDIAN machines. * On BIG_ENDIAN, the same code copies without reversing * the bytes. */ key_so_far = (((uint64_t)key[0] << 56) | ((uint64_t)key[1] << 48) | ((uint64_t)key[2] << 40) | ((uint64_t)key[3] << 32) | ((uint64_t)key[4] << 24) | ((uint64_t)key[5] << 16) | ((uint64_t)key[6] << 8) | (uint64_t)key[7]); #endif /* UNALIGNED_POINTERS_PERMITTED */ /* * Fix parity. */ fix_des_parity(&key_so_far); /* Do weak key check itself. */ for (i = 0; i < (sizeof (des_weak_keys) / sizeof (uint64_t)); i++) if (key_so_far == des_weak_keys[i]) { return (B_FALSE); } if (corrected_key != NULL) { #ifdef UNALIGNED_POINTERS_PERMITTED *(uint64_t *)(void *)&corrected_key[0] = htonll(key_so_far); #else /* * The code below reverses the bytes on LITTLE_ENDIAN machines. * On BIG_ENDIAN, the same code copies without reversing * the bytes. */ corrected_key[0] = key_so_far >> 56; corrected_key[1] = key_so_far >> 48; corrected_key[2] = key_so_far >> 40; corrected_key[3] = key_so_far >> 32; corrected_key[4] = key_so_far >> 24; corrected_key[5] = key_so_far >> 16; corrected_key[6] = key_so_far >> 8; corrected_key[7] = (uint8_t)key_so_far; #endif /* UNALIGNED_POINTERS_PERMITTED */ } return (B_TRUE); } static boolean_t des23_keycheck(uint8_t *key, uint8_t *corrected_key, boolean_t des3) { uint64_t aligned_key[DES3_KEYSIZE / sizeof (uint64_t)]; uint64_t key_so_far, scratch, *currentkey; uint_t j, num_weakkeys = 0; uint8_t keysize = DES3_KEYSIZE; uint8_t checks = 3; if (key == NULL) { return (B_FALSE); } if (des3 == B_FALSE) { keysize = DES2_KEYSIZE; checks = 2; } if (!IS_P2ALIGNED(key, sizeof (uint64_t))) { bcopy(key, aligned_key, keysize); currentkey = (uint64_t *)aligned_key; } else { /* LINTED */ currentkey = (uint64_t *)key; } for (j = 0; j < checks; j++) { key_so_far = currentkey[j]; if (!keycheck((uint8_t *)&key_so_far, (uint8_t *)&scratch)) { if (++num_weakkeys > 1) { return (B_FALSE); } /* * We found a weak key, but since * we've only found one weak key, * we can not reject the whole 3DES * set of keys as weak. * * Break from the weak key loop * (since this DES key is weak) and * continue on. */ } currentkey[j] = scratch; } /* * Perform key equivalence checks, now that parity is properly set. * 1st and 2nd keys must be unique, the 3rd key can be the same as * the 1st key for the 2 key variant of 3DES. */ if (currentkey[0] == currentkey[1] || currentkey[1] == currentkey[2]) return (B_FALSE); if (corrected_key != NULL) { bcopy(currentkey, corrected_key, keysize); } return (B_TRUE); } boolean_t des_keycheck(uint8_t *key, des_strength_t strength, uint8_t *corrected_key) { if (strength == DES) { return (keycheck(key, corrected_key)); } else if (strength == DES2) { return (des23_keycheck(key, corrected_key, B_FALSE)); } else if (strength == DES3) { return (des23_keycheck(key, corrected_key, B_TRUE)); } else { return (B_FALSE); } } void des_parity_fix(uint8_t *key, des_strength_t strength, uint8_t *corrected_key) { uint64_t aligned_key[DES3_KEYSIZE / sizeof (uint64_t)]; uint8_t *paritied_key; uint64_t key_so_far; int i = 0, offset = 0; if (strength == DES) bcopy(key, aligned_key, DES_KEYSIZE); else bcopy(key, aligned_key, DES3_KEYSIZE); paritied_key = (uint8_t *)aligned_key; while (strength > i) { offset = 8 * i; #ifdef UNALIGNED_POINTERS_PERMITTED key_so_far = htonll(*(uint64_t *)(void *)&paritied_key[offset]); #else key_so_far = (((uint64_t)paritied_key[offset + 0] << 56) | ((uint64_t)paritied_key[offset + 1] << 48) | ((uint64_t)paritied_key[offset + 2] << 40) | ((uint64_t)paritied_key[offset + 3] << 32) | ((uint64_t)paritied_key[offset + 4] << 24) | ((uint64_t)paritied_key[offset + 5] << 16) | ((uint64_t)paritied_key[offset + 6] << 8) | (uint64_t)paritied_key[offset + 7]); #endif /* UNALIGNED_POINTERS_PERMITTED */ fix_des_parity(&key_so_far); #ifdef UNALIGNED_POINTERS_PERMITTED *(uint64_t *)(void *)&paritied_key[offset] = htonll(key_so_far); #else paritied_key[offset + 0] = key_so_far >> 56; paritied_key[offset + 1] = key_so_far >> 48; paritied_key[offset + 2] = key_so_far >> 40; paritied_key[offset + 3] = key_so_far >> 32; paritied_key[offset + 4] = key_so_far >> 24; paritied_key[offset + 5] = key_so_far >> 16; paritied_key[offset + 6] = key_so_far >> 8; paritied_key[offset + 7] = (uint8_t)key_so_far; #endif /* UNALIGNED_POINTERS_PERMITTED */ i++; } bcopy(paritied_key, corrected_key, DES_KEYSIZE * strength); } /* * Initialize key schedule for DES, DES2, and DES3 */ void des_init_keysched(uint8_t *cipherKey, des_strength_t strength, void *ks) { uint64_t *encryption_ks; uint64_t *decryption_ks; uint64_t keysched[48]; uint64_t key_uint64[3]; uint64_t tmp; uint_t keysize, i, j; switch (strength) { case DES: keysize = DES_KEYSIZE; encryption_ks = ((keysched_t *)ks)->ksch_encrypt; decryption_ks = ((keysched_t *)ks)->ksch_decrypt; break; case DES2: keysize = DES2_KEYSIZE; encryption_ks = ((keysched3_t *)ks)->ksch_encrypt; decryption_ks = ((keysched3_t *)ks)->ksch_decrypt; break; case DES3: keysize = DES3_KEYSIZE; encryption_ks = ((keysched3_t *)ks)->ksch_encrypt; decryption_ks = ((keysched3_t *)ks)->ksch_decrypt; } /* * The code below, that is always executed on LITTLE_ENDIAN machines, * reverses every 8 bytes in the key. On BIG_ENDIAN, the same code * copies the key without reversing bytes. */ #ifdef _BIG_ENDIAN if (IS_P2ALIGNED(cipherKey, sizeof (uint64_t))) { for (i = 0, j = 0; j < keysize; i++, j += 8) { /* LINTED: pointer alignment */ key_uint64[i] = *((uint64_t *)&cipherKey[j]); } } else #endif /* _BIG_ENDIAN */ { for (i = 0, j = 0; j < keysize; i++, j += 8) { #ifdef UNALIGNED_POINTERS_PERMITTED key_uint64[i] = htonll(*(uint64_t *)(void *)&cipherKey[j]); #else key_uint64[i] = (((uint64_t)cipherKey[j] << 56) | ((uint64_t)cipherKey[j + 1] << 48) | ((uint64_t)cipherKey[j + 2] << 40) | ((uint64_t)cipherKey[j + 3] << 32) | ((uint64_t)cipherKey[j + 4] << 24) | ((uint64_t)cipherKey[j + 5] << 16) | ((uint64_t)cipherKey[j + 6] << 8) | (uint64_t)cipherKey[j + 7]); #endif /* UNALIGNED_POINTERS_PERMITTED */ } } switch (strength) { case DES: des_ks(keysched, key_uint64[0]); break; case DES2: /* DES2 is just DES3 with the first and third keys the same */ bcopy(key_uint64, key_uint64 + 2, DES_KEYSIZE); /* FALLTHRU */ case DES3: des_ks(keysched, key_uint64[0]); des_ks(keysched + 16, key_uint64[1]); for (i = 0; i < 8; i++) { tmp = keysched[16+i]; keysched[16+i] = keysched[31-i]; keysched[31-i] = tmp; } des_ks(keysched+32, key_uint64[2]); keysize = DES3_KEYSIZE; } /* save the encryption keyschedule */ bcopy(keysched, encryption_ks, keysize * 16); /* reverse the key schedule */ for (i = 0; i < keysize; i++) { tmp = keysched[i]; keysched[i] = keysched[2 * keysize - 1 - i]; keysched[2 * keysize -1 -i] = tmp; } /* save the decryption keyschedule */ bcopy(keysched, decryption_ks, keysize * 16); } /* * Allocate key schedule. */ /*ARGSUSED*/ void * des_alloc_keysched(size_t *keysched_size, des_strength_t strength, int kmflag) { void *keysched; size_t size; switch (strength) { case DES: size = sizeof (keysched_t); break; case DES2: case DES3: size = sizeof (keysched3_t); } #ifdef _KERNEL keysched = (keysched_t *)kmem_alloc(size, kmflag); #else /* !_KERNEL */ keysched = (keysched_t *)malloc(size); #endif /* _KERNEL */ if (keysched == NULL) return (NULL); if (keysched_size != NULL) *keysched_size = size; return (keysched); } /* * Replace the LSB of each byte by the xor of the other * 7 bits. The tricky thing is that the original contents of the LSBs * are nullified by including them twice in the xor computation. */ static void fix_des_parity(uint64_t *keyp) { uint64_t k = *keyp; k ^= k >> 1; k ^= k >> 2; k ^= k >> 4; *keyp ^= (k & 0x0101010101010101ULL); *keyp ^= 0x0101010101010101ULL; } void des_copy_block(uint8_t *in, uint8_t *out) { if (IS_P2ALIGNED(in, sizeof (uint32_t)) && IS_P2ALIGNED(out, sizeof (uint32_t))) { /* LINTED: pointer alignment */ *(uint32_t *)&out[0] = *(uint32_t *)&in[0]; /* LINTED: pointer alignment */ *(uint32_t *)&out[4] = *(uint32_t *)&in[4]; } else { DES_COPY_BLOCK(in, out); } } /* XOR block of data into dest */ void des_xor_block(uint8_t *data, uint8_t *dst) { if (IS_P2ALIGNED(dst, sizeof (uint32_t)) && IS_P2ALIGNED(data, sizeof (uint32_t))) { /* LINTED: pointer alignment */ *(uint32_t *)&dst[0] ^= /* LINTED: pointer alignment */ *(uint32_t *)&data[0]; /* LINTED: pointer alignment */ *(uint32_t *)&dst[4] ^= /* LINTED: pointer alignment */ *(uint32_t *)&data[4]; } else { DES_XOR_BLOCK(data, dst); } } int des_encrypt_block(const void *keysched, const uint8_t *in, uint8_t *out) { return (des_crunch_block(keysched, in, out, B_FALSE)); } int des3_encrypt_block(const void *keysched, const uint8_t *in, uint8_t *out) { return (des3_crunch_block(keysched, in, out, B_FALSE)); } int des_decrypt_block(const void *keysched, const uint8_t *in, uint8_t *out) { return (des_crunch_block(keysched, in, out, B_TRUE)); } int des3_decrypt_block(const void *keysched, const uint8_t *in, uint8_t *out) { return (des3_crunch_block(keysched, in, out, B_TRUE)); } /* * Encrypt multiple blocks of data according to mode. */ int des_encrypt_contiguous_blocks(void *ctx, char *data, size_t length, crypto_data_t *out) { des_ctx_t *des_ctx = ctx; int rv; if (des_ctx->dc_flags & DES3_STRENGTH) { if (des_ctx->dc_flags & CBC_MODE) { rv = cbc_encrypt_contiguous_blocks(ctx, data, length, out, DES_BLOCK_LEN, des3_encrypt_block, des_copy_block, des_xor_block); } else { rv = ecb_cipher_contiguous_blocks(ctx, data, length, out, DES_BLOCK_LEN, des3_encrypt_block); } } else { if (des_ctx->dc_flags & CBC_MODE) { rv = cbc_encrypt_contiguous_blocks(ctx, data, length, out, DES_BLOCK_LEN, des_encrypt_block, des_copy_block, des_xor_block); } else { rv = ecb_cipher_contiguous_blocks(ctx, data, length, out, DES_BLOCK_LEN, des_encrypt_block); } } return (rv); } /* * Decrypt multiple blocks of data according to mode. */ int des_decrypt_contiguous_blocks(void *ctx, char *data, size_t length, crypto_data_t *out) { des_ctx_t *des_ctx = ctx; int rv; if (des_ctx->dc_flags & DES3_STRENGTH) { if (des_ctx->dc_flags & CBC_MODE) { rv = cbc_decrypt_contiguous_blocks(ctx, data, length, out, DES_BLOCK_LEN, des3_decrypt_block, des_copy_block, des_xor_block); } else { rv = ecb_cipher_contiguous_blocks(ctx, data, length, out, DES_BLOCK_LEN, des3_decrypt_block); if (rv == CRYPTO_DATA_LEN_RANGE) rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE; } } else { if (des_ctx->dc_flags & CBC_MODE) { rv = cbc_decrypt_contiguous_blocks(ctx, data, length, out, DES_BLOCK_LEN, des_decrypt_block, des_copy_block, des_xor_block); } else { rv = ecb_cipher_contiguous_blocks(ctx, data, length, out, DES_BLOCK_LEN, des_decrypt_block); if (rv == CRYPTO_DATA_LEN_RANGE) rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE; } } return (rv); }