Changeset View
Changeset View
Standalone View
Standalone View
src/crypto/aes.cpp
Show First 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | if (pad) { | ||||
written += AES_BLOCKSIZE; | written += AES_BLOCKSIZE; | ||||
} | } | ||||
return written; | return written; | ||||
} | } | ||||
template <typename T> | template <typename T> | ||||
static int CBCDecrypt(const T &dec, const uint8_t iv[AES_BLOCKSIZE], | static int CBCDecrypt(const T &dec, const uint8_t iv[AES_BLOCKSIZE], | ||||
const uint8_t *data, int size, bool pad, uint8_t *out) { | const uint8_t *data, int size, bool pad, uint8_t *out) { | ||||
uint8_t padsize = 0; | |||||
int written = 0; | int written = 0; | ||||
bool fail = false; | bool fail = false; | ||||
const uint8_t *prev = iv; | const uint8_t *prev = iv; | ||||
if (!data || !size || !out) return 0; | if (!data || !size || !out) return 0; | ||||
if (size % AES_BLOCKSIZE != 0) return 0; | if (size % AES_BLOCKSIZE != 0) return 0; | ||||
// Decrypt all data. Padding will be checked in the output. | // Decrypt all data. Padding will be checked in the output. | ||||
while (written != size) { | while (written != size) { | ||||
dec.Decrypt(out, data + written); | dec.Decrypt(out, data + written); | ||||
for (int i = 0; i != AES_BLOCKSIZE; i++) | for (int i = 0; i != AES_BLOCKSIZE; i++) | ||||
*out++ ^= prev[i]; | *out++ ^= prev[i]; | ||||
prev = data + written; | prev = data + written; | ||||
written += AES_BLOCKSIZE; | written += AES_BLOCKSIZE; | ||||
} | } | ||||
// When decrypting padding, attempt to run in constant-time | // When decrypting padding, attempt to run in constant-time | ||||
if (pad) { | if (pad) { | ||||
// If used, padding size is the value of the last decrypted byte. For | // If used, padding size is the value of the last decrypted byte. For | ||||
// it to be valid, It must be between 1 and AES_BLOCKSIZE. | // it to be valid, It must be between 1 and AES_BLOCKSIZE. | ||||
padsize = *--out; | uint8_t padsize = *--out; | ||||
fail = !padsize | (padsize > AES_BLOCKSIZE); | fail = !padsize | (padsize > AES_BLOCKSIZE); | ||||
// If not well-formed, treat it as though there's no padding. | // If not well-formed, treat it as though there's no padding. | ||||
padsize *= !fail; | padsize *= !fail; | ||||
// All padding must equal the last byte otherwise it's not well-formed | // All padding must equal the last byte otherwise it's not well-formed | ||||
for (int i = AES_BLOCKSIZE; i != 0; i--) | for (int i = AES_BLOCKSIZE; i != 0; i--) | ||||
fail |= ((i > AES_BLOCKSIZE - padsize) & (*out-- != padsize)); | fail |= ((i > AES_BLOCKSIZE - padsize) & (*out-- != padsize)); | ||||
▲ Show 20 Lines • Show All 69 Lines • Show Last 20 Lines |