diff options
Diffstat (limited to 'src/lib/libcrypto/aes/aes_ctr.c')
| -rw-r--r-- | src/lib/libcrypto/aes/aes_ctr.c | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/src/lib/libcrypto/aes/aes_ctr.c b/src/lib/libcrypto/aes/aes_ctr.c index 59088499a0..79e1c18f19 100644 --- a/src/lib/libcrypto/aes/aes_ctr.c +++ b/src/lib/libcrypto/aes/aes_ctr.c | |||
| @@ -62,19 +62,49 @@ | |||
| 62 | /* NOTE: CTR mode is big-endian. The rest of the AES code | 62 | /* NOTE: CTR mode is big-endian. The rest of the AES code |
| 63 | * is endian-neutral. */ | 63 | * is endian-neutral. */ |
| 64 | 64 | ||
| 65 | /* increment counter (128-bit int) by 2^64 */ | 65 | /* increment counter (128-bit int) by 1 */ |
| 66 | static void AES_ctr128_inc(unsigned char *counter) { | 66 | static void AES_ctr128_inc(unsigned char *counter) { |
| 67 | unsigned long c; | 67 | unsigned long c; |
| 68 | 68 | ||
| 69 | /* Grab 3rd dword of counter and increment */ | 69 | /* Grab bottom dword of counter and increment */ |
| 70 | #ifdef L_ENDIAN | 70 | #ifdef L_ENDIAN |
| 71 | c = GETU32(counter + 8); | 71 | c = GETU32(counter + 0); |
| 72 | c++; | 72 | c++; |
| 73 | PUTU32(counter + 8, c); | 73 | PUTU32(counter + 0, c); |
| 74 | #else | 74 | #else |
| 75 | c = GETU32(counter + 4); | 75 | c = GETU32(counter + 12); |
| 76 | c++; | 76 | c++; |
| 77 | PUTU32(counter + 4, c); | 77 | PUTU32(counter + 12, c); |
| 78 | #endif | ||
| 79 | |||
| 80 | /* if no overflow, we're done */ | ||
| 81 | if (c) | ||
| 82 | return; | ||
| 83 | |||
| 84 | /* Grab 1st dword of counter and increment */ | ||
| 85 | #ifdef L_ENDIAN | ||
| 86 | c = GETU32(counter + 4); | ||
| 87 | c++; | ||
| 88 | PUTU32(counter + 4, c); | ||
| 89 | #else | ||
| 90 | c = GETU32(counter + 8); | ||
| 91 | c++; | ||
| 92 | PUTU32(counter + 8, c); | ||
| 93 | #endif | ||
| 94 | |||
| 95 | /* if no overflow, we're done */ | ||
| 96 | if (c) | ||
| 97 | return; | ||
| 98 | |||
| 99 | /* Grab 2nd dword of counter and increment */ | ||
| 100 | #ifdef L_ENDIAN | ||
| 101 | c = GETU32(counter + 8); | ||
| 102 | c++; | ||
| 103 | PUTU32(counter + 8, c); | ||
| 104 | #else | ||
| 105 | c = GETU32(counter + 4); | ||
| 106 | c++; | ||
| 107 | PUTU32(counter + 4, c); | ||
| 78 | #endif | 108 | #endif |
| 79 | 109 | ||
| 80 | /* if no overflow, we're done */ | 110 | /* if no overflow, we're done */ |
| @@ -100,10 +130,16 @@ static void AES_ctr128_inc(unsigned char *counter) { | |||
| 100 | * encrypted counter is kept in ecount_buf. Both *num and | 130 | * encrypted counter is kept in ecount_buf. Both *num and |
| 101 | * ecount_buf must be initialised with zeros before the first | 131 | * ecount_buf must be initialised with zeros before the first |
| 102 | * call to AES_ctr128_encrypt(). | 132 | * call to AES_ctr128_encrypt(). |
| 133 | * | ||
| 134 | * This algorithm assumes that the counter is in the x lower bits | ||
| 135 | * of the IV (ivec), and that the application has full control over | ||
| 136 | * overflow and the rest of the IV. This implementation takes NO | ||
| 137 | * responsability for checking that the counter doesn't overflow | ||
| 138 | * into the rest of the IV when incremented. | ||
| 103 | */ | 139 | */ |
| 104 | void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, | 140 | void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, |
| 105 | const unsigned long length, const AES_KEY *key, | 141 | const unsigned long length, const AES_KEY *key, |
| 106 | unsigned char counter[AES_BLOCK_SIZE], | 142 | unsigned char ivec[AES_BLOCK_SIZE], |
| 107 | unsigned char ecount_buf[AES_BLOCK_SIZE], | 143 | unsigned char ecount_buf[AES_BLOCK_SIZE], |
| 108 | unsigned int *num) { | 144 | unsigned int *num) { |
| 109 | 145 | ||
| @@ -117,8 +153,8 @@ void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, | |||
| 117 | 153 | ||
| 118 | while (l--) { | 154 | while (l--) { |
| 119 | if (n == 0) { | 155 | if (n == 0) { |
| 120 | AES_encrypt(counter, ecount_buf, key); | 156 | AES_encrypt(ivec, ecount_buf, key); |
| 121 | AES_ctr128_inc(counter); | 157 | AES_ctr128_inc(ivec); |
| 122 | } | 158 | } |
| 123 | *(out++) = *(in++) ^ ecount_buf[n]; | 159 | *(out++) = *(in++) ^ ecount_buf[n]; |
| 124 | n = (n+1) % AES_BLOCK_SIZE; | 160 | n = (n+1) % AES_BLOCK_SIZE; |
