62 const unsigned char *inp,
unsigned char *out,
65 const union {
long one;
char little; } is_endian = {1};
66 union {
u64 u[2];
u32 d[4];
u8 c[16]; } tweak, scratch;
69 if (len<16)
return -1;
71 memcpy(tweak.c, iv, 16);
75 if (!enc && (len%16)) len-=16;
78 #if defined(STRICT_ALIGNMENT)
79 memcpy(scratch.c,inp,16);
80 scratch.u[0] ^= tweak.u[0];
81 scratch.u[1] ^= tweak.u[1];
83 scratch.u[0] = ((
u64*)inp)[0]^tweak.u[0];
84 scratch.u[1] = ((
u64*)inp)[1]^tweak.u[1];
87 #if defined(STRICT_ALIGNMENT)
88 scratch.u[0] ^= tweak.u[0];
89 scratch.u[1] ^= tweak.u[1];
90 memcpy(out,scratch.c,16);
92 ((
u64*)out)[0] = scratch.u[0]^=tweak.u[0];
93 ((
u64*)out)[1] = scratch.u[1]^=tweak.u[1];
101 if (is_endian.little) {
102 unsigned int carry,res;
104 res = 0x87&(((int)tweak.d[3])>>31);
105 carry = (
unsigned int)(tweak.u[0]>>63);
106 tweak.u[0] = (tweak.u[0]<<1)^res;
107 tweak.u[1] = (tweak.u[1]<<1)|carry;
112 for (c=0,i=0;i<16;++i) {
114 c += ((size_t)tweak.c[i])<<1;
118 tweak.c[0] ^= (
u8)(0x87&(0-c));
122 for (i=0;i<
len;++i) {
124 out[i] = scratch.c[i];
127 scratch.u[0] ^= tweak.u[0];
128 scratch.u[1] ^= tweak.u[1];
129 (*ctx->
block1)(scratch.c,scratch.c,ctx->
key1);
130 scratch.u[0] ^= tweak.u[0];
131 scratch.u[1] ^= tweak.u[1];
132 memcpy(out-16,scratch.c,16);
135 union {
u64 u[2];
u8 c[16]; } tweak1;
137 if (is_endian.little) {
138 unsigned int carry,res;
140 res = 0x87&(((int)tweak.d[3])>>31);
141 carry = (
unsigned int)(tweak.u[0]>>63);
142 tweak1.u[0] = (tweak.u[0]<<1)^res;
143 tweak1.u[1] = (tweak.u[1]<<1)|carry;
148 for (c=0,i=0;i<16;++i) {
150 c += ((size_t)tweak.c[i])<<1;
154 tweak1.c[0] ^= (
u8)(0x87&(0-c));
156 #if defined(STRICT_ALIGNMENT)
157 memcpy(scratch.c,inp,16);
158 scratch.u[0] ^= tweak1.u[0];
159 scratch.u[1] ^= tweak1.u[1];
161 scratch.u[0] = ((
u64*)inp)[0]^tweak1.u[0];
162 scratch.u[1] = ((
u64*)inp)[1]^tweak1.u[1];
164 (*ctx->
block1)(scratch.c,scratch.c,ctx->
key1);
165 scratch.u[0] ^= tweak1.u[0];
166 scratch.u[1] ^= tweak1.u[1];
168 for (i=0;i<
len;++i) {
170 out[16+i] = scratch.c[i];
173 scratch.u[0] ^= tweak.u[0];
174 scratch.u[1] ^= tweak.u[1];
175 (*ctx->
block1)(scratch.c,scratch.c,ctx->
key1);
176 #if defined(STRICT_ALIGNMENT)
177 scratch.u[0] ^= tweak.u[0];
178 scratch.u[1] ^= tweak.u[1];
179 memcpy (out,scratch.c,16);
181 ((
u64*)out)[0] = scratch.u[0]^tweak.u[0];
182 ((
u64*)out)[1] = scratch.u[1]^tweak.u[1];