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 */