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
*** 19,34 ****
*
* CDDL HEADER END
*/
/*
! * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
- #pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Deimos - cryptographic acceleration based upon Broadcom 582x.
*/
#include <sys/types.h>
--- 19,32 ----
*
* CDDL HEADER END
*/
/*
! * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Deimos - cryptographic acceleration based upon Broadcom 582x.
*/
#include <sys/types.h>
*** 38,47 ****
--- 36,50 ----
#include <sys/note.h>
#include <sys/crypto/common.h>
#include <sys/crypto/spi.h>
#include <sys/crypto/dca.h>
+ #if defined(__i386) || defined(__amd64)
+ #include <sys/byteorder.h>
+ #define UNALIGNED_POINTERS_PERMITTED
+ #endif
+
/*
* 3DES implementation.
*/
static int dca_3desstart(dca_t *, uint32_t, dca_request_t *);
*** 72,84 ****
--- 75,93 ----
/*
* If cd_miscdata non-null then this contains the IV.
*/
if (in->cd_miscdata != NULL) {
+ #ifdef UNALIGNED_POINTERS_PERMITTED
+ uint32_t *p = (uint32_t *)in->cd_miscdata;
+ des_ctx->dr_ctx.iv[0] = htonl(p[0]);
+ des_ctx->dr_ctx.iv[1] = htonl(p[1]);
+ #else
uchar_t *p = (uchar_t *)in->cd_miscdata;
des_ctx->dr_ctx.iv[0] = p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3];
des_ctx->dr_ctx.iv[1] = p[4]<<24 | p[5]<<16 | p[6]<<8 | p[7];
+ #endif /* UNALIGNED_POINTERS_PERMITTED */
}
if (len > dca_length(out)) {
DBG(dca, DWARN, "inadequate output space (need %d, got %d)",
len, dca_length(out));
*** 166,178 ****
--- 175,193 ----
len = ROUNDDOWN(rawlen, DESBLOCK);
/*
* If cd_miscdata non-null then this contains the IV.
*/
if (in->cd_miscdata != NULL) {
+ #ifdef UNALIGNED_POINTERS_PERMITTED
+ uint32_t *p = (uint32_t *)in->cd_miscdata;
+ des_ctx->dr_ctx.iv[0] = htonl(p[0]);
+ des_ctx->dr_ctx.iv[1] = htonl(p[1]);
+ #else
uchar_t *p = (uchar_t *)in->cd_miscdata;
des_ctx->dr_ctx.iv[0] = p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3];
des_ctx->dr_ctx.iv[1] = p[4]<<24 | p[5]<<16 | p[6]<<8 | p[7];
+ #endif /* UNALIGNED_POINTERS_PERMITTED */
}
if (len > dca_length(out)) {
DBG(dca, DWARN, "not enough output space (need %d, got %d)",
len, dca_length(out));
*** 390,400 ****
--- 405,419 ----
* we will lose it. (For encrypt, we grab the IV AFTER encryption,
* in dca_3desdone.
*/
if (flags & DR_DECRYPT) {
uchar_t ivstore[DESBLOCK];
+ #ifdef UNALIGNED_POINTERS_PERMITTED
+ uint32_t *ivp = (uint32_t *)ivstore;
+ #else
uchar_t *ivp = ivstore;
+ #endif /* UNALIGNED_POINTERS_PERMITTED */
/* get last 8 bytes of ciphertext for IV of next op */
/*
* If we're processing only a DESBLOCKS worth of data
* and there is active residual present then it will be
*** 418,431 ****
--- 437,455 ----
"dca_3desstart: dca_getbufbytes() failed");
return (rv);
}
/* store as a pair of native 32-bit values */
+ #ifdef UNALIGNED_POINTERS_PERMITTED
+ ctx->dr_ctx.iv[0] = htonl(ivp[0]);
+ ctx->dr_ctx.iv[1] = htonl(ivp[1]);
+ #else
ctx->dr_ctx.iv[0] =
ivp[0]<<24 | ivp[1]<<16 | ivp[2]<<8 | ivp[3];
ctx->dr_ctx.iv[1] =
ivp[4]<<24 | ivp[5]<<16 | ivp[6]<<8 | ivp[7];
+ #endif /* UNALIGNED_POINTERS_PERMITTED */
}
/* For now we force a pullup. Add direct DMA later. */
reqp->dr_flags &= ~(DR_SCATTER | DR_GATHER);
if ((len < dca_mindma) || (ctx->dr_ctx.activeresidlen > 0) ||
*** 548,571 ****
* For encryption only, we have to grab the IV for the
* next pass AFTER encryption.
*/
if (reqp->dr_flags & DR_ENCRYPT) {
uchar_t ivstore[DESBLOCK];
uchar_t *iv = ivstore;
/* get last 8 bytes for IV of next op */
! errno = dca_getbufbytes(out, off, DESBLOCK, iv);
if (errno != CRYPTO_SUCCESS) {
DBG(NULL, DWARN,
"dca_3desdone: dca_getbufbytes() failed");
goto errout;
}
/* store as a pair of native 32-bit values */
ctx->dr_ctx.iv[0] =
iv[0]<<24 | iv[1]<<16 | iv[2]<<8 | iv[3];
ctx->dr_ctx.iv[1] =
iv[4]<<24 | iv[5]<<16 | iv[6]<<8 | iv[7];
}
/*
* If there is more to do, then reschedule another
* pass.
--- 572,606 ----
* For encryption only, we have to grab the IV for the
* next pass AFTER encryption.
*/
if (reqp->dr_flags & DR_ENCRYPT) {
uchar_t ivstore[DESBLOCK];
+ #ifdef UNALIGNED_POINTERS_PERMITTED
+ uint32_t *iv = (uint32_t *)ivstore;
+ #else
uchar_t *iv = ivstore;
+ #endif /* UNALIGNED_POINTERS_PERMITTED */
/* get last 8 bytes for IV of next op */
! errno = dca_getbufbytes(out, off, DESBLOCK,
! (uchar_t *)iv);
if (errno != CRYPTO_SUCCESS) {
DBG(NULL, DWARN,
"dca_3desdone: dca_getbufbytes() failed");
goto errout;
}
+
/* store as a pair of native 32-bit values */
+ #ifdef UNALIGNED_POINTERS_PERMITTED
+ ctx->dr_ctx.iv[0] = htonl(iv[0]);
+ ctx->dr_ctx.iv[1] = htonl(iv[1]);
+ #else
ctx->dr_ctx.iv[0] =
iv[0]<<24 | iv[1]<<16 | iv[2]<<8 | iv[3];
ctx->dr_ctx.iv[1] =
iv[4]<<24 | iv[5]<<16 | iv[6]<<8 | iv[7];
+ #endif /* UNALIGNED_POINTERS_PERMITTED */
}
/*
* If there is more to do, then reschedule another
* pass.
*** 621,638 ****
--- 656,683 ----
dca_3desctxinit(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
crypto_key_t *key, int kmflag, int flags)
{
dca_request_t *des_ctx;
dca_t *dca = ctx->cc_provider;
+ #ifdef UNALIGNED_POINTERS_PERMITTED
+ uint32_t *param;
+ uint32_t *value32;
+ #else
uchar_t *param;
+ #endif /* UNALIGNED_POINTERS_PERMITTED */
uchar_t *value;
size_t paramsz;
unsigned len;
int i, j;
paramsz = mechanism->cm_param_len;
+ #ifdef UNALIGNED_POINTERS_PERMITTED
+ param = (uint32_t *)mechanism->cm_param;
+ #else
param = (uchar_t *)mechanism->cm_param;
+ #endif /* UNALIGNED_POINTERS_PERMITTED */
+
if ((paramsz != 0) && (paramsz != DES_IV_LEN)) {
DBG(NULL, DWARN,
"dca_3desctxinit: parameter(IV) length not %d (%d)",
DES_IV_LEN, paramsz);
return (CRYPTO_MECHANISM_PARAM_INVALID);
*** 648,661 ****
--- 693,711 ----
* If cm_param == NULL then the IV comes from the cd_miscdata field
* in the crypto_data structure.
*/
if (param != NULL) {
ASSERT(paramsz == DES_IV_LEN);
+ #ifdef UNALIGNED_POINTERS_PERMITTED
+ des_ctx->dr_ctx.iv[0] = htonl(param[0]);
+ des_ctx->dr_ctx.iv[1] = htonl(param[1]);
+ #else
des_ctx->dr_ctx.iv[0] = param[0]<<24 | param[1]<<16 |
param[2]<<8 | param[3];
des_ctx->dr_ctx.iv[1] = param[4]<<24 | param[5]<<16 |
param[6]<<8 | param[7];
+ #endif /* UNALIGNED_POINTERS_PERMITTED */
}
des_ctx->dr_ctx.residlen = 0;
des_ctx->dr_ctx.activeresidlen = 0;
des_ctx->dr_ctx.ctx_cm_type = mechanism->cm_type;
ctx->cc_provider_private = des_ctx;
*** 707,720 ****
--- 757,778 ----
if (len != 64) {
DBG(NULL, DWARN, "Incorrect DES keysize (%d)", len);
dca_3desctxfree(ctx);
return (CRYPTO_KEY_SIZE_RANGE);
}
+
+ #ifdef UNALIGNED_POINTERS_PERMITTED
+ value32 = (uint32_t *)value;
+ des_ctx->dr_ctx.key[0] = htonl(value32[0]);
+ des_ctx->dr_ctx.key[1] = htonl(value32[1]);
+ #else
des_ctx->dr_ctx.key[0] =
value[0]<<24 | value[1]<<16 | value[2]<<8 | value[3];
des_ctx->dr_ctx.key[1] =
value[4]<<24 | value[5]<<16 | value[6]<<8 | value[7];
+ #endif /* UNALIGNED_POINTERS_PERMITTED */
+
/* for single des just repeat des key */
des_ctx->dr_ctx.key[4] =
des_ctx->dr_ctx.key[2] = des_ctx->dr_ctx.key[0];
des_ctx->dr_ctx.key[5] =
des_ctx->dr_ctx.key[3] = des_ctx->dr_ctx.key[1];