Add a return value to crypter_t.encrypt

This commit is contained in:
Martin Willi
2012-07-16 14:53:37 +02:00
parent c3858662d2
commit e35abbe588
21 changed files with 233 additions and 143 deletions
+6 -3
View File
@@ -104,9 +104,12 @@ int main(int argc, char *argv[])
while (i--) while (i--)
{ {
crypter->encrypt(crypter, if (!crypter->encrypt(crypter,
chunk_create(buffer, sizeof(buffer) / bs * bs), chunk_create(buffer, sizeof(buffer) / bs * bs),
chunk_create(iv, crypter->get_iv_size(crypter)), NULL); chunk_create(iv, crypter->get_iv_size(crypter)), NULL))
{
continue;
}
crypter->decrypt(crypter, crypter->decrypt(crypter,
chunk_create(buffer, sizeof(buffer) / bs * bs), chunk_create(buffer, sizeof(buffer) / bs * bs),
chunk_create(iv, crypter->get_iv_size(crypter)), NULL); chunk_create(iv, crypter->get_iv_size(crypter)), NULL);
@@ -337,9 +337,15 @@ static status_t ChallengeResponse(chunk_t challenge_hash, chunk_t password_hash,
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
chunk_t expanded, encrypted; chunk_t expanded, encrypted;
expanded = ExpandDESKey(keys[i]); expanded = ExpandDESKey(keys[i]);
crypter->set_key(crypter, expanded); crypter->set_key(crypter, expanded);
crypter->encrypt(crypter, challenge_hash, chunk_empty, &encrypted); if (!crypter->encrypt(crypter, challenge_hash, chunk_empty, &encrypted))
{
chunk_clear(&expanded);
crypter->destroy(crypter);
return FAILED;
}
memcpy(&response->ptr[i * 8], encrypted.ptr, encrypted.len); memcpy(&response->ptr[i * 8], encrypted.ptr, encrypted.len);
chunk_clear(&encrypted); chunk_clear(&encrypted);
chunk_clear(&expanded); chunk_clear(&expanded);
+1 -2
View File
@@ -167,8 +167,7 @@ METHOD(aead_t, encrypt, bool,
private_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv, private_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv,
chunk_t *encrypted) chunk_t *encrypted)
{ {
this->crypter->encrypt(this->crypter, plain, iv, encrypted); return this->crypter->encrypt(this->crypter, plain, iv, encrypted);
return TRUE;
} }
METHOD(aead_t, decrypt, bool, METHOD(aead_t, decrypt, bool,
+4 -1
View File
@@ -780,7 +780,10 @@ METHOD(simaka_message_t, generate, bool,
out = chunk_skip(out, iv.len); out = chunk_skip(out, iv.len);
/* inline encryption */ /* inline encryption */
crypter->encrypt(crypter, encr, iv, NULL); if (!crypter->encrypt(crypter, encr, iv, NULL))
{
return FALSE;
}
/* add ENCR_DATA attribute */ /* add ENCR_DATA attribute */
hdr = (attr_hdr_t*)out.ptr; hdr = (attr_hdr_t*)out.ptr;
+7 -3
View File
@@ -54,17 +54,21 @@ METHOD(aead_t, encrypt, bool,
if (encrypted) if (encrypted)
{ {
this->crypter->encrypt(this->crypter, plain, iv, &encr); if (!this->crypter->encrypt(this->crypter, plain, iv, &encr))
{
return FALSE;
}
if (!this->signer->allocate_signature(this->signer, encr, &sig)) if (!this->signer->allocate_signature(this->signer, encr, &sig))
{ {
free(encr.ptr);
return FALSE; return FALSE;
} }
*encrypted = chunk_cat("cmm", iv, encr, sig); *encrypted = chunk_cat("cmm", iv, encr, sig);
} }
else else
{ {
this->crypter->encrypt(this->crypter, plain, iv, NULL); if (!this->crypter->encrypt(this->crypter, plain, iv, NULL) ||
if (!this->signer->get_signature(this->signer, !this->signer->get_signature(this->signer,
plain, plain.ptr + plain.len)) plain, plain.ptr + plain.len))
{ {
return FALSE; return FALSE;
+3 -1
View File
@@ -90,8 +90,10 @@ struct crypter_t {
* @param data data to encrypt * @param data data to encrypt
* @param iv initializing vector * @param iv initializing vector
* @param encrypted chunk to allocate encrypted data, or NULL * @param encrypted chunk to allocate encrypted data, or NULL
* @return TRUE if encryption successful
*/ */
void (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv, __attribute__((warn_unused_result))
bool (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv,
chunk_t *encrypted); chunk_t *encrypted);
/** /**
+12 -4
View File
@@ -160,8 +160,10 @@ static u_int bench_crypter(private_crypto_tester_t *this,
start_timing(&start); start_timing(&start);
while (end_timing(&start) < this->bench_time) while (end_timing(&start) < this->bench_time)
{ {
crypter->encrypt(crypter, buf, chunk_from_thing(iv), NULL); if (crypter->encrypt(crypter, buf, chunk_from_thing(iv), NULL))
runs++; {
runs++;
}
crypter->decrypt(crypter, buf, chunk_from_thing(iv), NULL); crypter->decrypt(crypter, buf, chunk_from_thing(iv), NULL);
runs++; runs++;
} }
@@ -215,7 +217,10 @@ METHOD(crypto_tester_t, test_crypter, bool,
/* allocated encryption */ /* allocated encryption */
plain = chunk_create(vector->plain, vector->len); plain = chunk_create(vector->plain, vector->len);
crypter->encrypt(crypter, plain, iv, &cipher); if (!crypter->encrypt(crypter, plain, iv, &cipher))
{
failed = TRUE;
}
if (!memeq(vector->cipher, cipher.ptr, cipher.len)) if (!memeq(vector->cipher, cipher.ptr, cipher.len))
{ {
failed = TRUE; failed = TRUE;
@@ -235,7 +240,10 @@ METHOD(crypto_tester_t, test_crypter, bool,
failed = TRUE; failed = TRUE;
} }
/* inline encryption */ /* inline encryption */
crypter->encrypt(crypter, plain, iv, NULL); if (!crypter->encrypt(crypter, plain, iv, NULL))
{
failed = TRUE;
}
if (!memeq(vector->cipher, plain.ptr, plain.len)) if (!memeq(vector->cipher, plain.ptr, plain.len))
{ {
failed = TRUE; failed = TRUE;
+8 -1
View File
@@ -831,7 +831,14 @@ METHOD(pkcs7_t, build_envelopedData, bool,
/* symmetric encryption of data object */ /* symmetric encryption of data object */
crypter->set_key(crypter, symmetricKey); crypter->set_key(crypter, symmetricKey);
crypter->encrypt(crypter, in, iv, &out); if (!crypter->encrypt(crypter, in, iv, &out))
{
crypter->destroy(crypter);
chunk_clear(&in);
chunk_clear(&symmetricKey);
chunk_free(&iv);
return FALSE;
}
crypter->destroy(crypter); crypter->destroy(crypter);
chunk_clear(&in); chunk_clear(&in);
DBG3(DBG_LIB, " encrypted data: %B", &out); DBG3(DBG_LIB, " encrypted data: %B", &out);
+2 -1
View File
@@ -1373,7 +1373,7 @@ METHOD(crypter_t, decrypt, void,
} }
} }
METHOD(crypter_t, encrypt, void, METHOD(crypter_t, encrypt, bool,
private_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted) private_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
{ {
int pos; int pos;
@@ -1408,6 +1408,7 @@ METHOD(crypter_t, encrypt, void,
out+=16; out+=16;
pos+=16; pos+=16;
} }
return TRUE;
} }
METHOD(crypter_t, get_block_size, size_t, METHOD(crypter_t, get_block_size, size_t,
@@ -145,7 +145,7 @@ METHOD(crypter_t, decrypt, void,
} }
} }
METHOD(crypter_t, encrypt, void, METHOD(crypter_t, encrypt, bool,
private_af_alg_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) private_af_alg_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
{ {
if (dst) if (dst)
@@ -157,6 +157,7 @@ METHOD(crypter_t, encrypt, void,
{ {
this->ops->crypt(this->ops, ALG_OP_ENCRYPT, iv, data, data.ptr); this->ops->crypt(this->ops, ALG_OP_ENCRYPT, iv, data, data.ptr);
} }
return TRUE;
} }
METHOD(crypter_t, get_block_size, size_t, METHOD(crypter_t, get_block_size, size_t,
@@ -110,7 +110,7 @@ METHOD(crypter_t, decrypt, void,
free(iv.ptr); free(iv.ptr);
} }
METHOD(crypter_t, encrypt, void, METHOD(crypter_t, encrypt, bool,
private_blowfish_crypter_t *this, chunk_t data, chunk_t iv, private_blowfish_crypter_t *this, chunk_t data, chunk_t iv,
chunk_t *encrypted) chunk_t *encrypted)
{ {
@@ -131,6 +131,8 @@ METHOD(crypter_t, encrypt, void,
BF_cbc_encrypt(in, out, data.len, &this->schedule, iv.ptr, 1); BF_cbc_encrypt(in, out, data.len, &this->schedule, iv.ptr, 1);
free(iv.ptr); free(iv.ptr);
return TRUE;
} }
METHOD(crypter_t, get_block_size, size_t, METHOD(crypter_t, get_block_size, size_t,
+35 -30
View File
@@ -126,7 +126,7 @@ static void build_ctr(private_ccm_aead_t *this, u_int32_t i, chunk_t iv,
/** /**
* En-/Decrypt data * En-/Decrypt data
*/ */
static void crypt_data(private_ccm_aead_t *this, chunk_t iv, static bool crypt_data(private_ccm_aead_t *this, chunk_t iv,
chunk_t in, chunk_t out) chunk_t in, chunk_t out)
{ {
char ctr[BLOCK_SIZE]; char ctr[BLOCK_SIZE];
@@ -139,8 +139,11 @@ static void crypt_data(private_ccm_aead_t *this, chunk_t iv,
while (in.len > 0) while (in.len > 0)
{ {
memcpy(block, ctr, BLOCK_SIZE); memcpy(block, ctr, BLOCK_SIZE);
this->crypter->encrypt(this->crypter, chunk_from_thing(block), if (!this->crypter->encrypt(this->crypter, chunk_from_thing(block),
chunk_from_thing(zero), NULL); chunk_from_thing(zero), NULL))
{
return FALSE;
}
chunk_increment(chunk_from_thing(ctr)); chunk_increment(chunk_from_thing(ctr));
if (in.ptr != out.ptr) if (in.ptr != out.ptr)
@@ -151,12 +154,13 @@ static void crypt_data(private_ccm_aead_t *this, chunk_t iv,
in = chunk_skip(in, BLOCK_SIZE); in = chunk_skip(in, BLOCK_SIZE);
out = chunk_skip(out, BLOCK_SIZE); out = chunk_skip(out, BLOCK_SIZE);
} }
return TRUE;
} }
/** /**
* En-/Decrypt the ICV * En-/Decrypt the ICV
*/ */
static void crypt_icv(private_ccm_aead_t *this, chunk_t iv, char *icv) static bool crypt_icv(private_ccm_aead_t *this, chunk_t iv, char *icv)
{ {
char ctr[BLOCK_SIZE]; char ctr[BLOCK_SIZE];
char zero[BLOCK_SIZE]; char zero[BLOCK_SIZE];
@@ -164,15 +168,19 @@ static void crypt_icv(private_ccm_aead_t *this, chunk_t iv, char *icv)
build_ctr(this, 0, iv, ctr); build_ctr(this, 0, iv, ctr);
memset(zero, 0, BLOCK_SIZE); memset(zero, 0, BLOCK_SIZE);
this->crypter->encrypt(this->crypter, chunk_from_thing(ctr), if (!this->crypter->encrypt(this->crypter, chunk_from_thing(ctr),
chunk_from_thing(zero), NULL); chunk_from_thing(zero), NULL))
{
return FALSE;
}
memxor(icv, ctr, this->icv_size); memxor(icv, ctr, this->icv_size);
return TRUE;
} }
/** /**
* Create the ICV * Create the ICV
*/ */
static void create_icv(private_ccm_aead_t *this, chunk_t plain, chunk_t assoc, static bool create_icv(private_ccm_aead_t *this, chunk_t plain, chunk_t assoc,
chunk_t iv, char *icv) chunk_t iv, char *icv)
{ {
char zero[BLOCK_SIZE]; char zero[BLOCK_SIZE];
@@ -217,14 +225,19 @@ static void create_icv(private_ccm_aead_t *this, chunk_t plain, chunk_t assoc,
memset(pos, 0, len); memset(pos, 0, len);
/* encrypt inline with CBC, zero IV */ /* encrypt inline with CBC, zero IV */
this->crypter->encrypt(this->crypter, chunk, chunk_from_thing(zero), NULL); if (!this->crypter->encrypt(this->crypter, chunk,
chunk_from_thing(zero), NULL))
{
free(chunk.ptr);
return FALSE;
}
/* copy last icv_size bytes as ICV to output */ /* copy last icv_size bytes as ICV to output */
memcpy(icv, chunk.ptr + chunk.len - BLOCK_SIZE, this->icv_size); memcpy(icv, chunk.ptr + chunk.len - BLOCK_SIZE, this->icv_size);
/* encrypt the ICV value */
crypt_icv(this, iv, icv);
free(chunk.ptr); free(chunk.ptr);
/* encrypt the ICV value */
return crypt_icv(this, iv, icv);
} }
/** /**
@@ -235,9 +248,8 @@ static bool verify_icv(private_ccm_aead_t *this, chunk_t plain, chunk_t assoc,
{ {
char buf[this->icv_size]; char buf[this->icv_size];
create_icv(this, plain, assoc, iv, buf); return create_icv(this, plain, assoc, iv, buf) &&
memeq(buf, icv, this->icv_size);
return memeq(buf, icv, this->icv_size);
} }
METHOD(aead_t, encrypt, bool, METHOD(aead_t, encrypt, bool,
@@ -247,15 +259,11 @@ METHOD(aead_t, encrypt, bool,
if (encrypted) if (encrypted)
{ {
*encrypted = chunk_alloc(plain.len + this->icv_size); *encrypted = chunk_alloc(plain.len + this->icv_size);
create_icv(this, plain, assoc, iv, encrypted->ptr + plain.len); return create_icv(this, plain, assoc, iv, encrypted->ptr + plain.len) &&
crypt_data(this, iv, plain, *encrypted); crypt_data(this, iv, plain, *encrypted);
} }
else return create_icv(this, plain, assoc, iv, plain.ptr + plain.len) &&
{ crypt_data(this, iv, plain, plain);
create_icv(this, plain, assoc, iv, plain.ptr + plain.len);
crypt_data(this, iv, plain, plain);
}
return TRUE;
} }
METHOD(aead_t, decrypt, bool, METHOD(aead_t, decrypt, bool,
@@ -270,16 +278,13 @@ METHOD(aead_t, decrypt, bool,
if (plain) if (plain)
{ {
*plain = chunk_alloc(encrypted.len); *plain = chunk_alloc(encrypted.len);
crypt_data(this, iv, encrypted, *plain); return crypt_data(this, iv, encrypted, *plain) &&
return verify_icv(this, *plain, assoc, iv, verify_icv(this, *plain, assoc, iv,
encrypted.ptr + encrypted.len);
}
else
{
crypt_data(this, iv, encrypted, encrypted);
return verify_icv(this, encrypted, assoc, iv,
encrypted.ptr + encrypted.len); encrypted.ptr + encrypted.len);
} }
return crypt_data(this, iv, encrypted, encrypted) &&
verify_icv(this, encrypted, assoc, iv,
encrypted.ptr + encrypted.len);
} }
METHOD(aead_t, get_block_size, size_t, METHOD(aead_t, get_block_size, size_t,
+28 -9
View File
@@ -75,7 +75,7 @@ struct private_mac_t {
/** /**
* process supplied data, but do not run final operation * process supplied data, but do not run final operation
*/ */
static void update(private_mac_t *this, chunk_t data) static bool update(private_mac_t *this, chunk_t data)
{ {
chunk_t iv; chunk_t iv;
@@ -83,7 +83,7 @@ static void update(private_mac_t *this, chunk_t data)
{ /* no complete block (or last block), just copy into remaining */ { /* no complete block (or last block), just copy into remaining */
memcpy(this->remaining + this->remaining_bytes, data.ptr, data.len); memcpy(this->remaining + this->remaining_bytes, data.ptr, data.len);
this->remaining_bytes += data.len; this->remaining_bytes += data.len;
return; return TRUE;
} }
iv = chunk_alloca(this->b); iv = chunk_alloca(this->b);
@@ -100,7 +100,10 @@ static void update(private_mac_t *this, chunk_t data)
this->b - this->remaining_bytes); this->b - this->remaining_bytes);
data = chunk_skip(data, this->b - this->remaining_bytes); data = chunk_skip(data, this->b - this->remaining_bytes);
memxor(this->t, this->remaining, this->b); memxor(this->t, this->remaining, this->b);
this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL); if (!this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL))
{
return FALSE;
}
/* process blocks M_2 ... M_n-1 */ /* process blocks M_2 ... M_n-1 */
while (data.len > this->b) while (data.len > this->b)
@@ -108,18 +111,23 @@ static void update(private_mac_t *this, chunk_t data)
memcpy(this->remaining, data.ptr, this->b); memcpy(this->remaining, data.ptr, this->b);
data = chunk_skip(data, this->b); data = chunk_skip(data, this->b);
memxor(this->t, this->remaining, this->b); memxor(this->t, this->remaining, this->b);
this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL); if (!this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL))
{
return FALSE;
}
} }
/* store remaining bytes of block M_n */ /* store remaining bytes of block M_n */
memcpy(this->remaining, data.ptr, data.len); memcpy(this->remaining, data.ptr, data.len);
this->remaining_bytes = data.len; this->remaining_bytes = data.len;
return TRUE;
} }
/** /**
* process last block M_last * process last block M_last
*/ */
static void final(private_mac_t *this, u_int8_t *out) static bool final(private_mac_t *this, u_int8_t *out)
{ {
chunk_t iv; chunk_t iv;
@@ -156,24 +164,32 @@ static void final(private_mac_t *this, u_int8_t *out)
* T := AES-128(K,T); * T := AES-128(K,T);
*/ */
memxor(this->t, this->remaining, this->b); memxor(this->t, this->remaining, this->b);
this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL); if (!this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL))
{
return FALSE;
}
memcpy(out, this->t, this->b); memcpy(out, this->t, this->b);
/* reset state */ /* reset state */
memset(this->t, 0, this->b); memset(this->t, 0, this->b);
this->remaining_bytes = 0; this->remaining_bytes = 0;
return TRUE;
} }
METHOD(mac_t, get_mac, bool, METHOD(mac_t, get_mac, bool,
private_mac_t *this, chunk_t data, u_int8_t *out) private_mac_t *this, chunk_t data, u_int8_t *out)
{ {
/* update T, do not process last block */ /* update T, do not process last block */
update(this, data); if (!update(this, data))
{
return FALSE;
}
if (out) if (out)
{ /* if not in append mode, process last block and output result */ { /* if not in append mode, process last block and output result */
final(this, out); return final(this, out);
} }
return TRUE; return TRUE;
} }
@@ -264,7 +280,10 @@ METHOD(mac_t, set_key, bool,
l = chunk_alloca(this->b); l = chunk_alloca(this->b);
memset(l.ptr, 0, l.len); memset(l.ptr, 0, l.len);
this->k->set_key(this->k, resized); this->k->set_key(this->k, resized);
this->k->encrypt(this->k, l, iv, NULL); if (!this->k->encrypt(this->k, l, iv, NULL))
{
return FALSE;
}
derive_key(l); derive_key(l);
memcpy(this->k1, l.ptr, l.len); memcpy(this->k1, l.ptr, l.len);
derive_key(l); derive_key(l);
@@ -45,7 +45,7 @@ struct private_ctr_ipsec_crypter_t {
/** /**
* Do the CTR crypto operation * Do the CTR crypto operation
*/ */
static void crypt_ctr(private_ctr_ipsec_crypter_t *this, static bool crypt_ctr(private_ctr_ipsec_crypter_t *this,
chunk_t in, chunk_t out) chunk_t in, chunk_t out)
{ {
size_t is, bs; size_t is, bs;
@@ -63,8 +63,11 @@ static void crypt_ctr(private_ctr_ipsec_crypter_t *this,
memset(iv, 0, is); memset(iv, 0, is);
memcpy(block, state.ptr, bs); memcpy(block, state.ptr, bs);
this->crypter->encrypt(this->crypter, if (!this->crypter->encrypt(this->crypter, chunk_create(block, bs),
chunk_create(block, bs), chunk_create(iv, is), NULL); chunk_create(iv, is), NULL))
{
return FALSE;
}
chunk_increment(state); chunk_increment(state);
if (in.ptr != out.ptr) if (in.ptr != out.ptr)
@@ -75,9 +78,10 @@ static void crypt_ctr(private_ctr_ipsec_crypter_t *this,
in = chunk_skip(in, bs); in = chunk_skip(in, bs);
out = chunk_skip(out, bs); out = chunk_skip(out, bs);
} }
return TRUE;
} }
METHOD(crypter_t, crypt, void, METHOD(crypter_t, crypt, bool,
private_ctr_ipsec_crypter_t *this, chunk_t in, chunk_t iv, chunk_t *out) private_ctr_ipsec_crypter_t *this, chunk_t in, chunk_t iv, chunk_t *out)
{ {
memcpy(this->state.iv, iv.ptr, sizeof(this->state.iv)); memcpy(this->state.iv, iv.ptr, sizeof(this->state.iv));
@@ -85,12 +89,9 @@ METHOD(crypter_t, crypt, void,
if (out) if (out)
{ {
*out = chunk_alloc(in.len); *out = chunk_alloc(in.len);
crypt_ctr(this, in, *out); return crypt_ctr(this, in, *out);
}
else
{
crypt_ctr(this, in, in);
} }
return crypt_ctr(this, in, in);
} }
METHOD(crypter_t, get_block_size, size_t, METHOD(crypter_t, get_block_size, size_t,
+6 -3
View File
@@ -1434,7 +1434,7 @@ METHOD(crypter_t, decrypt, void,
} }
METHOD(crypter_t, encrypt, void, METHOD(crypter_t, encrypt, bool,
private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted) private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
{ {
des_cblock ivb; des_cblock ivb;
@@ -1449,6 +1449,7 @@ METHOD(crypter_t, encrypt, void,
memcpy(&ivb, iv.ptr, sizeof(des_cblock)); memcpy(&ivb, iv.ptr, sizeof(des_cblock));
des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out, des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
data.len, this->ks, &ivb, DES_ENCRYPT); data.len, this->ks, &ivb, DES_ENCRYPT);
return TRUE;
} }
METHOD(crypter_t, decrypt_ecb, void, METHOD(crypter_t, decrypt_ecb, void,
@@ -1466,7 +1467,7 @@ METHOD(crypter_t, decrypt_ecb, void,
data.len, this->ks, DES_DECRYPT); data.len, this->ks, DES_DECRYPT);
} }
METHOD(crypter_t, encrypt_ecb, void, METHOD(crypter_t, encrypt_ecb, bool,
private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted) private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
{ {
u_int8_t *out; u_int8_t *out;
@@ -1479,6 +1480,7 @@ METHOD(crypter_t, encrypt_ecb, void,
} }
des_ecb_encrypt((des_cblock*)(data.ptr), (des_cblock*)out, des_ecb_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
data.len, this->ks, DES_ENCRYPT); data.len, this->ks, DES_ENCRYPT);
return TRUE;
} }
METHOD(crypter_t, decrypt3, void, METHOD(crypter_t, decrypt3, void,
@@ -1499,7 +1501,7 @@ METHOD(crypter_t, decrypt3, void,
&ivb, DES_DECRYPT); &ivb, DES_DECRYPT);
} }
METHOD(crypter_t, encrypt3, void, METHOD(crypter_t, encrypt3, bool,
private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted) private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
{ {
des_cblock ivb; des_cblock ivb;
@@ -1515,6 +1517,7 @@ METHOD(crypter_t, encrypt3, void,
des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out, des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
data.len, this->ks3[0], this->ks3[1], this->ks3[2], data.len, this->ks3[0], this->ks3[1], this->ks3[2],
&ivb, DES_ENCRYPT); &ivb, DES_ENCRYPT);
return TRUE;
} }
METHOD(crypter_t, get_block_size, size_t, METHOD(crypter_t, get_block_size, size_t,
+29 -32
View File
@@ -149,7 +149,7 @@ static void ghash(private_gcm_aead_t *this, chunk_t x, char *res)
/** /**
* GCTR function, en-/decrypts x inline * GCTR function, en-/decrypts x inline
*/ */
static void gctr(private_gcm_aead_t *this, char *icb, chunk_t x) static bool gctr(private_gcm_aead_t *this, char *icb, chunk_t x)
{ {
char cb[BLOCK_SIZE], iv[BLOCK_SIZE], tmp[BLOCK_SIZE]; char cb[BLOCK_SIZE], iv[BLOCK_SIZE], tmp[BLOCK_SIZE];
@@ -159,12 +159,16 @@ static void gctr(private_gcm_aead_t *this, char *icb, chunk_t x)
while (x.len) while (x.len)
{ {
memcpy(tmp, cb, BLOCK_SIZE); memcpy(tmp, cb, BLOCK_SIZE);
this->crypter->encrypt(this->crypter, chunk_from_thing(tmp), if (!this->crypter->encrypt(this->crypter, chunk_from_thing(tmp),
chunk_from_thing(iv), NULL); chunk_from_thing(iv), NULL))
{
return FALSE;
}
memxor(x.ptr, tmp, min(BLOCK_SIZE, x.len)); memxor(x.ptr, tmp, min(BLOCK_SIZE, x.len));
chunk_increment(chunk_from_thing(cb)); chunk_increment(chunk_from_thing(cb));
x = chunk_skip(x, BLOCK_SIZE); x = chunk_skip(x, BLOCK_SIZE);
} }
return TRUE;
} }
/** /**
@@ -180,21 +184,21 @@ static void create_j(private_gcm_aead_t *this, char *iv, char *j)
/** /**
* Create GHASH subkey H * Create GHASH subkey H
*/ */
static void create_h(private_gcm_aead_t *this, char *h) static bool create_h(private_gcm_aead_t *this, char *h)
{ {
char zero[BLOCK_SIZE]; char zero[BLOCK_SIZE];
memset(zero, 0, BLOCK_SIZE); memset(zero, 0, BLOCK_SIZE);
memset(h, 0, BLOCK_SIZE); memset(h, 0, BLOCK_SIZE);
this->crypter->encrypt(this->crypter, chunk_create(h, BLOCK_SIZE), return this->crypter->encrypt(this->crypter, chunk_create(h, BLOCK_SIZE),
chunk_from_thing(zero), NULL); chunk_from_thing(zero), NULL);
} }
/** /**
* Encrypt/decrypt * Encrypt/decrypt
*/ */
static void crypt(private_gcm_aead_t *this, char *j, chunk_t in, chunk_t out) static bool crypt(private_gcm_aead_t *this, char *j, chunk_t in, chunk_t out)
{ {
char icb[BLOCK_SIZE]; char icb[BLOCK_SIZE];
@@ -206,13 +210,13 @@ static void crypt(private_gcm_aead_t *this, char *j, chunk_t in, chunk_t out)
{ {
memcpy(out.ptr, in.ptr, in.len); memcpy(out.ptr, in.ptr, in.len);
} }
gctr(this, icb, out); return gctr(this, icb, out);
} }
/** /**
* Create ICV * Create ICV
*/ */
static void create_icv(private_gcm_aead_t *this, chunk_t assoc, chunk_t crypt, static bool create_icv(private_gcm_aead_t *this, chunk_t assoc, chunk_t crypt,
char *j, char *icv) char *j, char *icv)
{ {
size_t assoc_pad, crypt_pad; size_t assoc_pad, crypt_pad;
@@ -249,9 +253,12 @@ static void create_icv(private_gcm_aead_t *this, chunk_t assoc, chunk_t crypt,
ghash(this, chunk, s); ghash(this, chunk, s);
free(chunk.ptr); free(chunk.ptr);
gctr(this, j, chunk_from_thing(s)); if (!gctr(this, j, chunk_from_thing(s)))
{
return FALSE;
}
memcpy(icv, s, this->icv_size); memcpy(icv, s, this->icv_size);
return TRUE;
} }
/** /**
@@ -262,9 +269,8 @@ static bool verify_icv(private_gcm_aead_t *this, chunk_t assoc, chunk_t crypt,
{ {
char tmp[this->icv_size]; char tmp[this->icv_size];
create_icv(this, assoc, crypt, j, tmp); return create_icv(this, assoc, crypt, j, tmp) &&
memeq(tmp, icv, this->icv_size);
return memeq(tmp, icv, this->icv_size);
} }
METHOD(aead_t, encrypt, bool, METHOD(aead_t, encrypt, bool,
@@ -278,17 +284,13 @@ METHOD(aead_t, encrypt, bool,
if (encrypted) if (encrypted)
{ {
*encrypted = chunk_alloc(plain.len + this->icv_size); *encrypted = chunk_alloc(plain.len + this->icv_size);
crypt(this, j, plain, *encrypted); return crypt(this, j, plain, *encrypted) &&
create_icv(this, assoc, create_icv(this, assoc,
chunk_create(encrypted->ptr, encrypted->len - this->icv_size), chunk_create(encrypted->ptr, encrypted->len - this->icv_size),
j, encrypted->ptr + encrypted->len - this->icv_size); j, encrypted->ptr + encrypted->len - this->icv_size);
} }
else return crypt(this, j, plain, plain) &&
{ create_icv(this, assoc, plain, j, plain.ptr + plain.len);
crypt(this, j, plain, plain);
create_icv(this, assoc, plain, j, plain.ptr + plain.len);
}
return TRUE;
} }
METHOD(aead_t, decrypt, bool, METHOD(aead_t, decrypt, bool,
@@ -312,13 +314,9 @@ METHOD(aead_t, decrypt, bool,
if (plain) if (plain)
{ {
*plain = chunk_alloc(encrypted.len); *plain = chunk_alloc(encrypted.len);
crypt(this, j, encrypted, *plain); return crypt(this, j, encrypted, *plain);
} }
else return crypt(this, j, encrypted, encrypted);
{
crypt(this, j, encrypted, encrypted);
}
return TRUE;
} }
METHOD(aead_t, get_block_size, size_t, METHOD(aead_t, get_block_size, size_t,
@@ -351,8 +349,7 @@ METHOD(aead_t, set_key, bool,
memcpy(this->salt, key.ptr + key.len - SALT_SIZE, SALT_SIZE); memcpy(this->salt, key.ptr + key.len - SALT_SIZE, SALT_SIZE);
key.len -= SALT_SIZE; key.len -= SALT_SIZE;
this->crypter->set_key(this->crypter, key); this->crypter->set_key(this->crypter, key);
create_h(this, this->h); return create_h(this, this->h);
return TRUE;
} }
METHOD(aead_t, destroy, void, METHOD(aead_t, destroy, void,
@@ -59,18 +59,15 @@ struct private_gcrypt_crypter_t {
/** /**
* Set the IV for en/decryption * Set the IV for en/decryption
*/ */
static void set_iv(private_gcrypt_crypter_t *this, chunk_t iv) static bool set_iv(private_gcrypt_crypter_t *this, chunk_t iv)
{ {
if (this->ctr_mode) if (this->ctr_mode)
{ {
memcpy(this->ctr.iv, iv.ptr, sizeof(this->ctr.iv)); memcpy(this->ctr.iv, iv.ptr, sizeof(this->ctr.iv));
this->ctr.counter = htonl(1); this->ctr.counter = htonl(1);
gcry_cipher_setctr(this->h, &this->ctr, sizeof(this->ctr)); return gcry_cipher_setctr(this->h, &this->ctr, sizeof(this->ctr)) == 0;
}
else
{
gcry_cipher_setiv(this->h, iv.ptr, iv.len);
} }
return gcry_cipher_setiv(this->h, iv.ptr, iv.len) == 0;
} }
METHOD(crypter_t, decrypt, void, METHOD(crypter_t, decrypt, void,
@@ -89,20 +86,20 @@ METHOD(crypter_t, decrypt, void,
} }
} }
METHOD(crypter_t, encrypt, void, METHOD(crypter_t, encrypt, bool,
private_gcrypt_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) private_gcrypt_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
{ {
set_iv(this, iv); if (!set_iv(this, iv))
{
return FALSE;
}
if (dst) if (dst)
{ {
*dst = chunk_alloc(data.len); *dst = chunk_alloc(data.len);
gcry_cipher_encrypt(this->h, dst->ptr, dst->len, data.ptr, data.len); return gcry_cipher_encrypt(this->h, dst->ptr, dst->len,
} data.ptr, data.len) == 0;
else
{
gcry_cipher_encrypt(this->h, data.ptr, data.len, NULL, 0);
} }
return gcry_cipher_encrypt(this->h, data.ptr, data.len, NULL, 0) == 0;
} }
METHOD(crypter_t, get_block_size, size_t, METHOD(crypter_t, get_block_size, size_t,
@@ -90,7 +90,7 @@ static char* lookup_algorithm(u_int16_t ikev2_algo, size_t *key_size)
/** /**
* Do the actual en/decryption in an EVP context * Do the actual en/decryption in an EVP context
*/ */
static void crypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv, static bool crypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv,
chunk_t *dst, int enc) chunk_t *dst, int enc)
{ {
int len; int len;
@@ -104,13 +104,14 @@ static void crypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv,
} }
EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx); EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, this->cipher, NULL, NULL, NULL, enc); return EVP_CipherInit_ex(&ctx, this->cipher, NULL, NULL, NULL, enc) &&
EVP_CIPHER_CTX_set_padding(&ctx, 0); /* disable padding */ EVP_CIPHER_CTX_set_padding(&ctx, 0) /* disable padding */ &&
EVP_CIPHER_CTX_set_key_length(&ctx, this->key.len); EVP_CIPHER_CTX_set_key_length(&ctx, this->key.len) &&
EVP_CipherInit_ex(&ctx, NULL, NULL, this->key.ptr, iv.ptr, enc); EVP_CipherInit_ex(&ctx, NULL, NULL, this->key.ptr, iv.ptr, enc) &&
EVP_CipherUpdate(&ctx, out, &len, data.ptr, data.len); EVP_CipherUpdate(&ctx, out, &len, data.ptr, data.len) &&
EVP_CipherFinal_ex(&ctx, out + len, &len); /* since padding is disabled this does nothing */ /* since padding is disabled this does nothing */
EVP_CIPHER_CTX_cleanup(&ctx); EVP_CipherFinal_ex(&ctx, out + len, &len) &&
EVP_CIPHER_CTX_cleanup(&ctx);
} }
METHOD(crypter_t, decrypt, void, METHOD(crypter_t, decrypt, void,
@@ -119,10 +120,10 @@ METHOD(crypter_t, decrypt, void,
crypt(this, data, iv, dst, 0); crypt(this, data, iv, dst, 0);
} }
METHOD(crypter_t, encrypt, void, METHOD(crypter_t, encrypt, bool,
private_openssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) private_openssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
{ {
crypt(this, data, iv, dst, 1); return crypt(this, data, iv, dst, 1);
} }
METHOD(crypter_t, get_block_size, size_t, METHOD(crypter_t, get_block_size, size_t,
@@ -115,10 +115,11 @@ METHOD(crypter_t, decrypt, void,
crypt(this, iv.ptr, data, dst, TRUE); crypt(this, iv.ptr, data, dst, TRUE);
} }
METHOD(crypter_t, encrypt, void, METHOD(crypter_t, encrypt, bool,
private_padlock_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) private_padlock_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
{ {
crypt(this, iv.ptr, data, dst, FALSE); crypt(this, iv.ptr, data, dst, FALSE);
return TRUE;
} }
METHOD(crypter_t, get_block_size, size_t, METHOD(crypter_t, get_block_size, size_t,
+36 -15
View File
@@ -81,7 +81,7 @@ struct private_mac_t {
/** /**
* xcbc supplied data, but do not run final operation * xcbc supplied data, but do not run final operation
*/ */
static void update(private_mac_t *this, chunk_t data) static bool update(private_mac_t *this, chunk_t data)
{ {
chunk_t iv; chunk_t iv;
@@ -94,7 +94,7 @@ static void update(private_mac_t *this, chunk_t data)
{ /* no complete block, just copy into remaining */ { /* no complete block, just copy into remaining */
memcpy(this->remaining + this->remaining_bytes, data.ptr, data.len); memcpy(this->remaining + this->remaining_bytes, data.ptr, data.len);
this->remaining_bytes += data.len; this->remaining_bytes += data.len;
return; return TRUE;
} }
iv = chunk_alloca(this->b); iv = chunk_alloca(this->b);
@@ -110,7 +110,10 @@ static void update(private_mac_t *this, chunk_t data)
this->b - this->remaining_bytes); this->b - this->remaining_bytes);
data = chunk_skip(data, this->b - this->remaining_bytes); data = chunk_skip(data, this->b - this->remaining_bytes);
memxor(this->e, this->remaining, this->b); memxor(this->e, this->remaining, this->b);
this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL); if (!this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL))
{
return FALSE;
}
/* process blocks M[2] ... M[n-1] */ /* process blocks M[2] ... M[n-1] */
while (data.len > this->b) while (data.len > this->b)
@@ -118,18 +121,24 @@ static void update(private_mac_t *this, chunk_t data)
memcpy(this->remaining, data.ptr, this->b); memcpy(this->remaining, data.ptr, this->b);
data = chunk_skip(data, this->b); data = chunk_skip(data, this->b);
memxor(this->e, this->remaining, this->b); memxor(this->e, this->remaining, this->b);
this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL); if (!this->k1->encrypt(this->k1, chunk_create(this->e, this->b),
iv, NULL))
{
return FALSE;
}
} }
/* store remaining bytes of block M[n] */ /* store remaining bytes of block M[n] */
memcpy(this->remaining, data.ptr, data.len); memcpy(this->remaining, data.ptr, data.len);
this->remaining_bytes = data.len; this->remaining_bytes = data.len;
return TRUE;
} }
/** /**
* run last round, data is in this->e * run last round, data is in this->e
*/ */
static void final(private_mac_t *this, u_int8_t *out) static bool final(private_mac_t *this, u_int8_t *out)
{ {
chunk_t iv; chunk_t iv;
@@ -145,7 +154,6 @@ static void final(private_mac_t *this, u_int8_t *out)
*/ */
memxor(this->e, this->remaining, this->b); memxor(this->e, this->remaining, this->b);
memxor(this->e, this->k2, this->b); memxor(this->e, this->k2, this->b);
this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL);
} }
else else
{ {
@@ -168,7 +176,10 @@ static void final(private_mac_t *this, u_int8_t *out)
*/ */
memxor(this->e, this->remaining, this->b); memxor(this->e, this->remaining, this->b);
memxor(this->e, this->k3, this->b); memxor(this->e, this->k3, this->b);
this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL); }
if (!this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL))
{
return FALSE;
} }
memcpy(out, this->e, this->b); memcpy(out, this->e, this->b);
@@ -177,17 +188,22 @@ static void final(private_mac_t *this, u_int8_t *out)
memset(this->e, 0, this->b); memset(this->e, 0, this->b);
this->remaining_bytes = 0; this->remaining_bytes = 0;
this->zero = TRUE; this->zero = TRUE;
return TRUE;
} }
METHOD(mac_t, get_mac, bool, METHOD(mac_t, get_mac, bool,
private_mac_t *this, chunk_t data, u_int8_t *out) private_mac_t *this, chunk_t data, u_int8_t *out)
{ {
/* update E, do not process last block */ /* update E, do not process last block */
update(this, data); if (!update(this, data))
{
return FALSE;
}
if (out) if (out)
{ /* if not in append mode, process last block and output result */ { /* if not in append mode, process last block and output result */
final(this, out); return final(this, out);
} }
return TRUE; return TRUE;
} }
@@ -236,13 +252,18 @@ METHOD(mac_t, set_key, bool,
* K2 = 0x02020202020202020202020202020202 encrypted with Key K * K2 = 0x02020202020202020202020202020202 encrypted with Key K
* K3 = 0x03030303030303030303030303030303 encrypted with Key K * K3 = 0x03030303030303030303030303030303 encrypted with Key K
*/ */
this->k1->set_key(this->k1, lengthened);
memset(this->k2, 0x02, this->b);
this->k1->encrypt(this->k1, chunk_create(this->k2, this->b), iv, NULL);
memset(this->k3, 0x03, this->b);
this->k1->encrypt(this->k1, chunk_create(this->k3, this->b), iv, NULL);
memset(k1.ptr, 0x01, this->b); memset(k1.ptr, 0x01, this->b);
this->k1->encrypt(this->k1, k1, iv, NULL); memset(this->k2, 0x02, this->b);
memset(this->k3, 0x03, this->b);
this->k1->set_key(this->k1, lengthened);
if (!this->k1->encrypt(this->k1, chunk_create(this->k2, this->b), iv, NULL) ||
!this->k1->encrypt(this->k1, chunk_create(this->k3, this->b), iv, NULL) ||
!this->k1->encrypt(this->k1, k1, iv, NULL))
{
return FALSE;
}
this->k1->set_key(this->k1, k1); this->k1->set_key(this->k1, k1);
memwipe(k1.ptr, k1.len); memwipe(k1.ptr, k1.len);
+10 -1
View File
@@ -256,7 +256,16 @@ METHOD(tls_protection_t, build, status_t,
*data = chunk_cat("mmcc", *data, mac, padding, *data = chunk_cat("mmcc", *data, mac, padding,
chunk_from_thing(padding_length)); chunk_from_thing(padding_length));
/* encrypt inline */ /* encrypt inline */
this->crypter_out->encrypt(this->crypter_out, *data, iv, NULL); if (!this->crypter_out->encrypt(this->crypter_out, *data,
iv, NULL))
{
if (!this->iv_out.len)
{
free(iv.ptr);
}
free(data->ptr);
return FAILED;
}
if (this->iv_out.len) if (this->iv_out.len)
{ /* next record IV is last ciphertext block of this record */ { /* next record IV is last ciphertext block of this record */