Print this page
5007142 Add ntohll and htonll to sys/byteorder.h
6717509 Need to use bswap/bswapq for byte swap of 64-bit integer on x32/x64
PSARC 2008/474

*** 21,32 **** /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - #pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/systm.h> #include <sys/ddi.h> #include <sys/sysmacros.h> #include <sys/strsun.h> --- 21,30 ----
*** 37,46 **** --- 35,49 ---- #ifndef _KERNEL #include <strings.h> #include <stdlib.h> #endif /* !_KERNEL */ + #if defined(__i386) || defined(__amd64) + #include <sys/byteorder.h> + #define UNALIGNED_POINTERS_PERMITTED + #endif + /* EXPORT DELETE START */ typedef struct keysched_s { uint64_t ksch_encrypt[16]; uint64_t ksch_decrypt[16];
*** 516,559 **** 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 uint64_t tmp; 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]); if (decrypt == B_TRUE) tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 3); else tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 3); 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; ! #ifdef _BIG_ENDIAN } - #endif /* EXPORT DELETE END */ return (CRYPTO_SUCCESS); } int --- 519,567 ---- 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 *)&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 *)&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 */ } /* EXPORT DELETE END */ return (CRYPTO_SUCCESS); } int
*** 572,616 **** 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 uint64_t tmp; 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]); if (decrypt == B_TRUE) tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 1); else tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 1); 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; ! #ifdef _BIG_ENDIAN } - #endif /* EXPORT DELETE END */ return (CRYPTO_SUCCESS); } static boolean_t --- 580,630 ---- 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 *)&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 *)&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 */ } /* EXPORT DELETE END */ return (CRYPTO_SUCCESS); } static boolean_t
*** 648,674 **** 0x1fe01fe00ef10ef1ULL, 0xe01fe01ff10ef10eULL, 0x01e001e001f101f1ULL, 0xe001e001f101f101ULL, 0x1ffe1ffe0efe0efeULL, 0xfe1ffe1ffe0efe0eULL, 0x011f011f010e010eULL, 0x1f011f010e010e01ULL, 0xe0fee0fef1fef1feULL, 0xfee0fee0fef1fef1ULL, ! #endif /* We'll save the other possibly-weak keys for the future. */ }; if (key == NULL) return (B_FALSE); /* * 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]); /* * Fix parity. */ fix_des_parity(&key_so_far); --- 662,692 ---- 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 *)&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);
*** 678,687 **** --- 696,708 ---- if (key_so_far == des_weak_keys[i]) { return (B_FALSE); } if (corrected_key != NULL) { + #ifdef UNALIGNED_POINTERS_PERMITTED + *(uint64_t *)&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. */
*** 691,700 **** --- 712,722 ---- 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 */ } /* EXPORT DELETE END */ return (B_TRUE); }
*** 741,751 **** } /* * 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 varient of 3DES. */ if (currentkey[0] == currentkey[1] || currentkey[1] == currentkey[2]) return (B_FALSE); if (corrected_key != NULL) { --- 763,773 ---- } /* * 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) {
*** 783,811 **** --- 805,841 ---- 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 *)&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 *)&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);
*** 853,879 **** 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 { for (i = 0, j = 0; j < keysize; i++, j += 8) { 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]); } } - #ifdef _BIG_ENDIAN - } - #endif switch (strength) { case DES: des_ks(keysched, key_uint64[0]); break; --- 883,910 ---- 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 *)&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;
*** 949,959 **** } /* * 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 nullifed by including them twice in the xor computation. */ static void fix_des_parity(uint64_t *keyp) { /* EXPORT DELETE START */ --- 980,990 ---- } /* * 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) { /* EXPORT DELETE START */