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; |