{
chunk_t iv, padding, to_crypt, result;
rng_t *rng;
- status_t status;
size_t block_size;
if (this->signer == NULL || this->crypter == NULL)
/* encrypt to_crypt chunk */
free(this->encrypted.ptr);
- status = this->crypter->encrypt(this->crypter, to_crypt, iv, &result);
+ this->crypter->encrypt(this->crypter, to_crypt, iv, &result);
free(padding.ptr);
free(to_crypt.ptr);
- if (status != SUCCESS)
- {
- DBG2(DBG_ENC, "encryption failed");
- free(iv.ptr);
- return status;
- }
+
DBG3(DBG_ENC, "data after encryption %B", &result);
/* build encrypted result with iv and signature */
{
chunk_t iv, concatenated;
u_int8_t padding_length;
- status_t status;
DBG2(DBG_ENC, "decrypting encryption payload");
DBG3(DBG_ENC, "data before decryption with IV and (invalid) signature %B",
/* point concatenated to data + padding + padding_length*/
concatenated.ptr = this->encrypted.ptr + iv.len;
- concatenated.len = this->encrypted.len - iv.len - this->signer->get_block_size(this->signer);
+ concatenated.len = this->encrypted.len - iv.len -
+ this->signer->get_block_size(this->signer);
- /* check the size of input:
- * concatenated must be at least on block_size of crypter
- */
- if (concatenated.len < iv.len)
+ /* concatenated must be a multiple of block_size of crypter */
+ if (concatenated.len < iv.len || concatenated.len % iv.len)
{
DBG1(DBG_ENC, "could not decrypt, invalid input");
return FAILED;
DBG3(DBG_ENC, "data before decryption %B", &concatenated);
- status = this->crypter->decrypt(this->crypter, concatenated, iv, &(this->decrypted));
- if (status != SUCCESS)
- {
- DBG1(DBG_ENC, "could not decrypt, decryption failed");
- return FAILED;
- }
+ this->crypter->decrypt(this->crypter, concatenated, iv, &this->decrypted);
+
DBG3(DBG_ENC, "data after decryption with padding %B", &this->decrypted);
-
/* get padding length, sits just bevore signature */
padding_length = *(this->decrypted.ptr + this->decrypted.len - 1);
- /* add one byte to the padding length, since the padding_length field is not included */
+ /* add one byte to the padding length, since the padding_length field is
+ * not included */
padding_length++;
this->decrypted.len -= padding_length;
/* decrypt blob */
crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size);
crypter->set_key(crypter, key);
- if (crypter->decrypt(crypter, *blob, *iv, &decrypted) != SUCCESS)
+
+ if (iv->len != crypter->get_block_size(crypter) ||
+ blob->len % iv->len)
{
crypter->destroy(crypter);
return "data size is not multiple of block size";
}
+ crypter->decrypt(crypter, *blob, *iv, &decrypted);
crypter->destroy(crypter);
memcpy(blob->ptr, decrypted.ptr, blob->len);
chunk_free(&decrypted);
/**
* Encrypt a chunk of data and allocate space for the encrypted value.
*
+ * The length of the iv must equal to get_block_size(), while the length
+ * of data must be a multiple it.
+ *
* @param data data to encrypt
* @param iv initializing vector
- * @param encrypted pointer where the encrypted bytes will be written
- * @return SUCCESS, or INVALID_ARG if size invalid
+ * @param encrypted chunk to allocate encrypted data
*/
- status_t (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv,
- chunk_t *encrypted);
+ void (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *encrypted);
/**
* Decrypt a chunk of data and allocate space for the decrypted value.
+ *
+ * The length of the iv must equal to get_block_size(), while the length
+ * of data must be a multiple it.
*
* @param data data to decrypt
* @param iv initializing vector
- * @param encrypted pointer where the decrypted bytes will be written
- * @return SUCCESS, or INVALID_ARG if invalid
+ * @param encrypted chunk to allocate decrypted data
*/
- status_t (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv,
- chunk_t *decrypted);
+ void (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *decrypted);
/**
* Get the block size of the crypto algorithm.
/**
* Set the key.
- *
+ *
+ * The length of the key must match get_key_size().
+ *
* @param key key to set
- * @return SUCCESS, or INVALID_ARG if key length invalid
*/
- status_t (*set_key) (crypter_t *this, chunk_t key);
+ void (*set_key) (crypter_t *this, chunk_t key);
/**
* Destroys a crypter_t object.
* Key size of this AES cypher object.
*/
u_int32_t key_size;
-
- /**
- * Decrypts a block.
- *
- * No memory gets allocated.
- *
- * @param this calling object
- * @param[in] in_blk block to decrypt
- * @param[out] out_blk decrypted data are written to this location
- */
- void (*decrypt_block) (const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
-
- /**
- * Encrypts a block.
- *
- * No memory gets allocated.
- *
- * @param this calling object
- * @param[in] in_blk block to encrypt
- * @param[out] out_blk encrypted data are written to this location
- */
- void (*encrypt_block) (const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
};
#endif
/**
- * Implementation of private_aes_crypter_t.encrypt_block.
+ * Encrypt a single block of data.
*/
static void encrypt_block(const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
{ u_int32_t locals(b0, b1);
}
/**
- * Implementation of private_aes_crypter_t.decrypt_block.
+ * Decrypt a single block of data.
*/
static void decrypt_block(const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
{ u_int32_t locals(b0, b1);
/**
* Implementation of crypter_t.decrypt.
*/
-static status_t decrypt (private_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
+static void decrypt(private_aes_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *decrypted)
{
- int ret, pos;
+ int pos;
const u_int32_t *iv_i;
u_int8_t *in, *out;
- ret = data.len;
- if (((data.len) % 16) != 0)
- {
- /* data length must be padded to a multiple of blocksize */
- return INVALID_ARG;
- }
-
- decrypted->ptr = malloc(data.len);
- if (decrypted->ptr == NULL)
- {
- return OUT_OF_RES;
- }
- decrypted->len = data.len;
-
+ *decrypted = chunk_alloc(data.len);
in = data.ptr;
out = decrypted->ptr;
- pos=data.len-16;
- in+=pos;
- out+=pos;
- while(pos>=0) {
- this->decrypt_block(this,in,out);
+ pos = data.len-16;
+ in += pos;
+ out += pos;
+ while (pos >= 0)
+ {
+ decrypt_block(this, in, out);
if (pos==0)
+ {
iv_i=(const u_int32_t*) (iv.ptr);
+ }
else
+ {
iv_i=(const u_int32_t*) (in-16);
+ }
*((u_int32_t *)(&out[ 0])) ^= iv_i[0];
*((u_int32_t *)(&out[ 4])) ^= iv_i[1];
*((u_int32_t *)(&out[ 8])) ^= iv_i[2];
out-=16;
pos-=16;
}
-
- return SUCCESS;
}
/**
* Implementation of crypter_t.decrypt.
*/
-static status_t encrypt (private_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
+static void encrypt (private_aes_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *encrypted)
{
- int ret, pos;
+ int pos;
const u_int32_t *iv_i;
u_int8_t *in, *out;
- ret = data.len;
- if (((data.len) % 16) != 0)
- {
- /* data length must be padded to a multiple of blocksize */
- return INVALID_ARG;
- }
-
- encrypted->ptr = malloc(data.len);
- if (encrypted->ptr == NULL)
- {
- return OUT_OF_RES;
- }
- encrypted->len = data.len;
-
+ *encrypted = chunk_alloc(data.len);
in = data.ptr;
out = encrypted->ptr;
while(pos<data.len)
{
if (pos==0)
+ {
iv_i=(const u_int32_t*) iv.ptr;
+ }
else
+ {
iv_i=(const u_int32_t*) (out-16);
+ }
*((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0]));
*((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4]));
*((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8]));
*((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12]));
- this->encrypt_block(this,out,out);
+ encrypt_block(this, out, out);
in+=16;
out+=16;
pos+=16;
}
- return SUCCESS;
}
/**
/**
* Implementation of crypter_t.set_key.
*/
-static status_t set_key (private_aes_crypter_t *this, chunk_t key)
+static void set_key (private_aes_crypter_t *this, chunk_t key)
{
u_int32_t *kf, *kt, rci, f = 0;
u_int8_t *in_key = key.ptr;
- if (key.len != this->key_size)
- {
- return INVALID_ARG;
- }
-
this->aes_Nrnd = (this->aes_Nkey > (nc) ? this->aes_Nkey : (nc)) + 6;
this->aes_e_key[0] = const_word_in(in_key );
}
cpy(kt, kf);
}
-
- return SUCCESS;
}
/**
return NULL;
}
- /* functions of crypter_t interface */
- this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
- this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
- this->public.crypter_interface.set_key = (status_t (*) (crypter_t *,chunk_t)) set_key;
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key;
this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
- /* private functions */
- this->decrypt_block = decrypt_block;
- this->encrypt_block = encrypt_block;
-
return &(this->public);
}
/**
* Implementation of crypter_t.decrypt for DES.
*/
-static status_t decrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
+static void decrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *decrypted)
{
des_cblock ivb;
- if (data.len % sizeof(des_cblock) != 0 ||
- iv.len != sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
*decrypted = chunk_alloc(data.len);
memcpy(&ivb, iv.ptr, sizeof(des_cblock));
des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(decrypted->ptr),
data.len, this->ks, &ivb, DES_DECRYPT);
- return SUCCESS;
}
/**
* Implementation of crypter_t.decrypt for DES.
*/
-static status_t encrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
+static void encrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *encrypted)
{
des_cblock ivb;
- if (data.len % sizeof(des_cblock) != 0 ||
- iv.len != sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
*encrypted = chunk_alloc(data.len);
memcpy(&ivb, iv.ptr, sizeof(des_cblock));
des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(encrypted->ptr),
data.len, this->ks, &ivb, DES_ENCRYPT);
- return SUCCESS;
}
/**
* Implementation of crypter_t.decrypt for 3DES.
*/
-static status_t decrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
+static void decrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *decrypted)
{
des_cblock ivb;
- if (data.len % sizeof(des_cblock) != 0 ||
- iv.len != sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
*decrypted = chunk_alloc(data.len);
memcpy(&ivb, iv.ptr, sizeof(des_cblock));
des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(decrypted->ptr),
data.len, this->ks3[0], this->ks3[1], this->ks3[2],
&ivb, DES_DECRYPT);
- return SUCCESS;
}
/**
* Implementation of crypter_t.decrypt for 3DES.
*/
-static status_t encrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
+static void encrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *encrypted)
{
des_cblock ivb;
- if (data.len % sizeof(des_cblock) != 0 ||
- iv.len != sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
*encrypted = chunk_alloc(data.len);
memcpy(&ivb, iv.ptr, sizeof(des_cblock));
des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(encrypted->ptr),
data.len, this->ks3[0], this->ks3[1], this->ks3[2],
&ivb, DES_ENCRYPT);
- return SUCCESS;
}
/**
/**
* Implementation of crypter_t.set_key for DES.
*/
-static status_t set_key(private_des_crypter_t *this, chunk_t key)
+static void set_key(private_des_crypter_t *this, chunk_t key)
{
- if (key.len != sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
des_set_key((des_cblock*)(key.ptr), &this->ks);
-
- return SUCCESS;
}
/**
* Implementation of crypter_t.set_key for 3DES.
*/
-static status_t set_key3(private_des_crypter_t *this, chunk_t key)
-{
- if (key.len != 3 * sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
+static void set_key3(private_des_crypter_t *this, chunk_t key)
+{
des_set_key((des_cblock*)(key.ptr) + 0, &this->ks3[0]);
des_set_key((des_cblock*)(key.ptr) + 1, &this->ks3[1]);
des_set_key((des_cblock*)(key.ptr) + 2, &this->ks3[2]);
-
- return SUCCESS;
}
/**
{
case ENCR_DES:
this->key_size = sizeof(des_cblock);
- this->public.crypter_interface.set_key = (status_t (*) (crypter_t *,chunk_t)) set_key;
- this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
- this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key;
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
break;
case ENCR_3DES:
this->key_size = 3 * sizeof(des_cblock);
- this->public.crypter_interface.set_key = (status_t (*) (crypter_t *,chunk_t)) set_key3;
- this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt3;
- this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt3;
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key3;
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt3;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt3;
break;
default:
free(this);
return NULL;
}
- return &(this->public);
+ return &this->public;
}