diff options
author | jsing <> | 2025-05-25 06:24:37 +0000 |
---|---|---|
committer | jsing <> | 2025-05-25 06:24:37 +0000 |
commit | e10b3fc3007b5ea0fdd7a0977201e503aca26aff (patch) | |
tree | 6f16c2c6198fd113344db2eacc7482ba2338d964 /src | |
parent | c6df6a0771a9ec35fccf75afa610a77310ea351d (diff) | |
download | openbsd-e10b3fc3007b5ea0fdd7a0977201e503aca26aff.tar.gz openbsd-e10b3fc3007b5ea0fdd7a0977201e503aca26aff.tar.bz2 openbsd-e10b3fc3007b5ea0fdd7a0977201e503aca26aff.zip |
Simplify AES-IGE and remove code with implementation defined behaviour.
Remove the UNALIGNED_MEMOPS_ARE_FAST from AES-IGE, which can result in
implementation defined behaviour on i386/amd64. While we could keep this
purely for aligned inputs and outputs, it's probably not that important
and can be redone in a simpler form later if we want to do so.
ok tb@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/aes/aes_ige.c | 157 |
1 files changed, 40 insertions, 117 deletions
diff --git a/src/lib/libcrypto/aes/aes_ige.c b/src/lib/libcrypto/aes/aes_ige.c index 1a6fcfcfbf..1330397573 100644 --- a/src/lib/libcrypto/aes/aes_ige.c +++ b/src/lib/libcrypto/aes/aes_ige.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: aes_ige.c,v 1.10 2024/03/30 05:14:12 joshua Exp $ */ | 1 | /* $OpenBSD: aes_ige.c,v 1.11 2025/05/25 06:24:37 jsing Exp $ */ |
2 | /* ==================================================================== | 2 | /* ==================================================================== |
3 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. |
4 | * | 4 | * |
@@ -59,137 +59,60 @@ typedef struct { | |||
59 | unsigned long data[N_WORDS]; | 59 | unsigned long data[N_WORDS]; |
60 | } aes_block_t; | 60 | } aes_block_t; |
61 | 61 | ||
62 | /* XXX: probably some better way to do this */ | ||
63 | #if defined(__i386__) || defined(__x86_64__) | ||
64 | #define UNALIGNED_MEMOPS_ARE_FAST 1 | ||
65 | #else | ||
66 | #define UNALIGNED_MEMOPS_ARE_FAST 0 | ||
67 | #endif | ||
68 | |||
69 | #if UNALIGNED_MEMOPS_ARE_FAST | ||
70 | #define load_block(d, s) (d) = *(const aes_block_t *)(s) | ||
71 | #define store_block(d, s) *(aes_block_t *)(d) = (s) | ||
72 | #else | ||
73 | #define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE) | ||
74 | #define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE) | ||
75 | #endif | ||
76 | |||
77 | /* N.B. The IV for this mode is _twice_ the block size */ | ||
78 | |||
79 | void | 62 | void |
80 | AES_ige_encrypt(const unsigned char *in, unsigned char *out, size_t length, | 63 | AES_ige_encrypt(const unsigned char *in, unsigned char *out, size_t length, |
81 | const AES_KEY *key, unsigned char *ivec, const int enc) | 64 | const AES_KEY *key, unsigned char *ivec, const int enc) |
82 | { | 65 | { |
66 | aes_block_t tmp, tmp2; | ||
67 | aes_block_t iv; | ||
68 | aes_block_t iv2; | ||
83 | size_t n; | 69 | size_t n; |
84 | size_t len; | 70 | size_t len; |
85 | 71 | ||
72 | /* N.B. The IV for this mode is _twice_ the block size */ | ||
73 | |||
86 | OPENSSL_assert((length % AES_BLOCK_SIZE) == 0); | 74 | OPENSSL_assert((length % AES_BLOCK_SIZE) == 0); |
87 | 75 | ||
88 | len = length / AES_BLOCK_SIZE; | 76 | len = length / AES_BLOCK_SIZE; |
89 | 77 | ||
90 | if (AES_ENCRYPT == enc) { | 78 | memcpy(iv.data, ivec, AES_BLOCK_SIZE); |
91 | if (in != out && (UNALIGNED_MEMOPS_ARE_FAST || | 79 | memcpy(iv2.data, ivec + AES_BLOCK_SIZE, AES_BLOCK_SIZE); |
92 | ((size_t)in|(size_t)out|(size_t)ivec) % | ||
93 | sizeof(long) == 0)) { | ||
94 | aes_block_t *ivp = (aes_block_t *)ivec; | ||
95 | aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE); | ||
96 | |||
97 | while (len) { | ||
98 | aes_block_t *inp = (aes_block_t *)in; | ||
99 | aes_block_t *outp = (aes_block_t *)out; | ||
100 | |||
101 | for (n = 0; n < N_WORDS; ++n) | ||
102 | outp->data[n] = inp->data[n] ^ ivp->data[n]; | ||
103 | AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key); | ||
104 | for (n = 0; n < N_WORDS; ++n) | ||
105 | outp->data[n] ^= iv2p->data[n]; | ||
106 | ivp = outp; | ||
107 | iv2p = inp; | ||
108 | --len; | ||
109 | in += AES_BLOCK_SIZE; | ||
110 | out += AES_BLOCK_SIZE; | ||
111 | } | ||
112 | memmove(ivec, ivp->data, AES_BLOCK_SIZE); | ||
113 | memmove(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); | ||
114 | } else { | ||
115 | aes_block_t tmp, tmp2; | ||
116 | aes_block_t iv; | ||
117 | aes_block_t iv2; | ||
118 | 80 | ||
119 | load_block(iv, ivec); | 81 | if (AES_ENCRYPT == enc) { |
120 | load_block(iv2, ivec + AES_BLOCK_SIZE); | 82 | while (len) { |
121 | 83 | memcpy(tmp.data, in, AES_BLOCK_SIZE); | |
122 | while (len) { | 84 | for (n = 0; n < N_WORDS; ++n) |
123 | load_block(tmp, in); | 85 | tmp2.data[n] = tmp.data[n] ^ iv.data[n]; |
124 | for (n = 0; n < N_WORDS; ++n) | 86 | AES_encrypt((unsigned char *)tmp2.data, |
125 | tmp2.data[n] = tmp.data[n] ^ iv.data[n]; | 87 | (unsigned char *)tmp2.data, key); |
126 | AES_encrypt((unsigned char *)tmp2.data, | 88 | for (n = 0; n < N_WORDS; ++n) |
127 | (unsigned char *)tmp2.data, key); | 89 | tmp2.data[n] ^= iv2.data[n]; |
128 | for (n = 0; n < N_WORDS; ++n) | 90 | memcpy(out, tmp2.data, AES_BLOCK_SIZE); |
129 | tmp2.data[n] ^= iv2.data[n]; | 91 | iv = tmp2; |
130 | store_block(out, tmp2); | 92 | iv2 = tmp; |
131 | iv = tmp2; | 93 | --len; |
132 | iv2 = tmp; | 94 | in += AES_BLOCK_SIZE; |
133 | --len; | 95 | out += AES_BLOCK_SIZE; |
134 | in += AES_BLOCK_SIZE; | ||
135 | out += AES_BLOCK_SIZE; | ||
136 | } | ||
137 | memcpy(ivec, iv.data, AES_BLOCK_SIZE); | ||
138 | memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); | ||
139 | } | 96 | } |
140 | } else { | 97 | } else { |
141 | if (in != out && (UNALIGNED_MEMOPS_ARE_FAST || | 98 | while (len) { |
142 | ((size_t)in|(size_t)out|(size_t)ivec) % | 99 | memcpy(tmp.data, in, AES_BLOCK_SIZE); |
143 | sizeof(long) == 0)) { | 100 | tmp2 = tmp; |
144 | aes_block_t *ivp = (aes_block_t *)ivec; | 101 | for (n = 0; n < N_WORDS; ++n) |
145 | aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE); | 102 | tmp.data[n] ^= iv2.data[n]; |
146 | 103 | AES_decrypt((unsigned char *)tmp.data, | |
147 | while (len) { | 104 | (unsigned char *)tmp.data, key); |
148 | aes_block_t tmp; | 105 | for (n = 0; n < N_WORDS; ++n) |
149 | aes_block_t *inp = (aes_block_t *)in; | 106 | tmp.data[n] ^= iv.data[n]; |
150 | aes_block_t *outp = (aes_block_t *)out; | 107 | memcpy(out, tmp.data, AES_BLOCK_SIZE); |
151 | 108 | iv = tmp2; | |
152 | for (n = 0; n < N_WORDS; ++n) | 109 | iv2 = tmp; |
153 | tmp.data[n] = inp->data[n] ^ iv2p->data[n]; | 110 | --len; |
154 | AES_decrypt((unsigned char *)tmp.data, | 111 | in += AES_BLOCK_SIZE; |
155 | (unsigned char *)outp->data, key); | 112 | out += AES_BLOCK_SIZE; |
156 | for (n = 0; n < N_WORDS; ++n) | ||
157 | outp->data[n] ^= ivp->data[n]; | ||
158 | ivp = inp; | ||
159 | iv2p = outp; | ||
160 | --len; | ||
161 | in += AES_BLOCK_SIZE; | ||
162 | out += AES_BLOCK_SIZE; | ||
163 | } | ||
164 | memmove(ivec, ivp->data, AES_BLOCK_SIZE); | ||
165 | memmove(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); | ||
166 | } else { | ||
167 | aes_block_t tmp, tmp2; | ||
168 | aes_block_t iv; | ||
169 | aes_block_t iv2; | ||
170 | |||
171 | load_block(iv, ivec); | ||
172 | load_block(iv2, ivec + AES_BLOCK_SIZE); | ||
173 | |||
174 | while (len) { | ||
175 | load_block(tmp, in); | ||
176 | tmp2 = tmp; | ||
177 | for (n = 0; n < N_WORDS; ++n) | ||
178 | tmp.data[n] ^= iv2.data[n]; | ||
179 | AES_decrypt((unsigned char *)tmp.data, | ||
180 | (unsigned char *)tmp.data, key); | ||
181 | for (n = 0; n < N_WORDS; ++n) | ||
182 | tmp.data[n] ^= iv.data[n]; | ||
183 | store_block(out, tmp); | ||
184 | iv = tmp2; | ||
185 | iv2 = tmp; | ||
186 | --len; | ||
187 | in += AES_BLOCK_SIZE; | ||
188 | out += AES_BLOCK_SIZE; | ||
189 | } | ||
190 | memcpy(ivec, iv.data, AES_BLOCK_SIZE); | ||
191 | memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); | ||
192 | } | 113 | } |
193 | } | 114 | } |
115 | memcpy(ivec, iv.data, AES_BLOCK_SIZE); | ||
116 | memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); | ||
194 | } | 117 | } |
195 | LCRYPTO_ALIAS(AES_ige_encrypt); | 118 | LCRYPTO_ALIAS(AES_ige_encrypt); |