diff options
| author | djm <> | 2012-10-13 21:23:50 +0000 |
|---|---|---|
| committer | djm <> | 2012-10-13 21:23:50 +0000 |
| commit | d56dbc3c72494d4b68c03f5bcc3ae1f9df7b17df (patch) | |
| tree | 10ebe51c3542099b0ab8325d8f322372375dc3b4 /src/lib/libcrypto/modes/ctr128.c | |
| parent | bc685bd401e5657f7fb51b4e1a62a7a5c5ea4098 (diff) | |
| parent | 228cae30b117c2493f69ad3c195341cd6ec8d430 (diff) | |
| download | openbsd-d56dbc3c72494d4b68c03f5bcc3ae1f9df7b17df.tar.gz openbsd-d56dbc3c72494d4b68c03f5bcc3ae1f9df7b17df.tar.bz2 openbsd-d56dbc3c72494d4b68c03f5bcc3ae1f9df7b17df.zip | |
This commit was generated by cvs2git to track changes on a CVS vendor
branch.
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/modes/ctr128.c | 92 |
1 files changed, 80 insertions, 12 deletions
diff --git a/src/lib/libcrypto/modes/ctr128.c b/src/lib/libcrypto/modes/ctr128.c index 932037f551..ee642c5863 100644 --- a/src/lib/libcrypto/modes/ctr128.c +++ b/src/lib/libcrypto/modes/ctr128.c | |||
| @@ -48,7 +48,8 @@ | |||
| 48 | * | 48 | * |
| 49 | */ | 49 | */ |
| 50 | 50 | ||
| 51 | #include "modes.h" | 51 | #include <openssl/crypto.h> |
| 52 | #include "modes_lcl.h" | ||
| 52 | #include <string.h> | 53 | #include <string.h> |
| 53 | 54 | ||
| 54 | #ifndef MODES_DEBUG | 55 | #ifndef MODES_DEBUG |
| @@ -58,17 +59,6 @@ | |||
| 58 | #endif | 59 | #endif |
| 59 | #include <assert.h> | 60 | #include <assert.h> |
| 60 | 61 | ||
| 61 | typedef unsigned int u32; | ||
| 62 | typedef unsigned char u8; | ||
| 63 | |||
| 64 | #define STRICT_ALIGNMENT | ||
| 65 | #if defined(__i386) || defined(__i386__) || \ | ||
| 66 | defined(__x86_64) || defined(__x86_64__) || \ | ||
| 67 | defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ | ||
| 68 | defined(__s390__) || defined(__s390x__) | ||
| 69 | # undef STRICT_ALIGNMENT | ||
| 70 | #endif | ||
| 71 | |||
| 72 | /* NOTE: the IV/counter CTR mode is big-endian. The code itself | 62 | /* NOTE: the IV/counter CTR mode is big-endian. The code itself |
| 73 | * is endian-neutral. */ | 63 | * is endian-neutral. */ |
| 74 | 64 | ||
| @@ -182,3 +172,81 @@ void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, | |||
| 182 | 172 | ||
| 183 | *num=n; | 173 | *num=n; |
| 184 | } | 174 | } |
| 175 | |||
| 176 | /* increment upper 96 bits of 128-bit counter by 1 */ | ||
| 177 | static void ctr96_inc(unsigned char *counter) { | ||
| 178 | u32 n=12; | ||
| 179 | u8 c; | ||
| 180 | |||
| 181 | do { | ||
| 182 | --n; | ||
| 183 | c = counter[n]; | ||
| 184 | ++c; | ||
| 185 | counter[n] = c; | ||
| 186 | if (c) return; | ||
| 187 | } while (n); | ||
| 188 | } | ||
| 189 | |||
| 190 | void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, | ||
| 191 | size_t len, const void *key, | ||
| 192 | unsigned char ivec[16], unsigned char ecount_buf[16], | ||
| 193 | unsigned int *num, ctr128_f func) | ||
| 194 | { | ||
| 195 | unsigned int n,ctr32; | ||
| 196 | |||
| 197 | assert(in && out && key && ecount_buf && num); | ||
| 198 | assert(*num < 16); | ||
| 199 | |||
| 200 | n = *num; | ||
| 201 | |||
| 202 | while (n && len) { | ||
| 203 | *(out++) = *(in++) ^ ecount_buf[n]; | ||
| 204 | --len; | ||
| 205 | n = (n+1) % 16; | ||
| 206 | } | ||
| 207 | |||
| 208 | ctr32 = GETU32(ivec+12); | ||
| 209 | while (len>=16) { | ||
| 210 | size_t blocks = len/16; | ||
| 211 | /* | ||
| 212 | * 1<<28 is just a not-so-small yet not-so-large number... | ||
| 213 | * Below condition is practically never met, but it has to | ||
| 214 | * be checked for code correctness. | ||
| 215 | */ | ||
| 216 | if (sizeof(size_t)>sizeof(unsigned int) && blocks>(1U<<28)) | ||
| 217 | blocks = (1U<<28); | ||
| 218 | /* | ||
| 219 | * As (*func) operates on 32-bit counter, caller | ||
| 220 | * has to handle overflow. 'if' below detects the | ||
| 221 | * overflow, which is then handled by limiting the | ||
| 222 | * amount of blocks to the exact overflow point... | ||
| 223 | */ | ||
| 224 | ctr32 += (u32)blocks; | ||
| 225 | if (ctr32 < blocks) { | ||
| 226 | blocks -= ctr32; | ||
| 227 | ctr32 = 0; | ||
| 228 | } | ||
| 229 | (*func)(in,out,blocks,key,ivec); | ||
| 230 | /* (*ctr) does not update ivec, caller does: */ | ||
| 231 | PUTU32(ivec+12,ctr32); | ||
| 232 | /* ... overflow was detected, propogate carry. */ | ||
| 233 | if (ctr32 == 0) ctr96_inc(ivec); | ||
| 234 | blocks *= 16; | ||
| 235 | len -= blocks; | ||
| 236 | out += blocks; | ||
| 237 | in += blocks; | ||
| 238 | } | ||
| 239 | if (len) { | ||
| 240 | memset(ecount_buf,0,16); | ||
| 241 | (*func)(ecount_buf,ecount_buf,1,key,ivec); | ||
| 242 | ++ctr32; | ||
| 243 | PUTU32(ivec+12,ctr32); | ||
| 244 | if (ctr32 == 0) ctr96_inc(ivec); | ||
| 245 | while (len--) { | ||
| 246 | out[n] = in[n] ^ ecount_buf[n]; | ||
| 247 | ++n; | ||
| 248 | } | ||
| 249 | } | ||
| 250 | |||
| 251 | *num=n; | ||
| 252 | } | ||
