Hi List;
I am using ocf-linux in an openwrt application and have run into
MAX_DATA_LEN (64K-1) and E2BIG errors in CRYPTO_AES_CBC mode.
As a consequence, I need to split the input buffer into chunks <
MAX_DATA_LEN and process chunks individually and assemble the resultant
plaintext / ciphertext chunks into a large output buffer.
Google has sparse results and no code regarding this issue. Wikipedia
indicates this is possible by feeding the previous iv to the next block
operation:
https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_ch
aining_.28CBC.29
Description: CBC encryption.svg
Description: CBC decryption.svg
QUESTIONS/POINT:
1 - Is this possible using ocf-linux?
2 - Has anyone run into / solved this issue and have (pseudo) code (best
practice) to share to save me re-inventing the wheel?
My current encrypt / decrypt functions (working for < MAX_DATA_LEN) follow:
int aes_encrypt(struct cryptodev_ctx* ctx, const void* iv, const void*
plaintext, void* ciphertext, size_t size)
{
struct crypt_op cryp;
void* p;
/* check plaintext and ciphertext alignment */
if (ctx->alignmask) {
p = (void*)(((unsigned long)plaintext + ctx->alignmask) &
~ctx->alignmask);
if (plaintext != p) {
DebugPrintf( DEBUG_ERR, "%s: plaintext is not aligned\n",
__func__);
return ERROR;
}
p = (void*)(((unsigned long)ciphertext + ctx->alignmask) &
~ctx->alignmask);
if (ciphertext != p) {
DebugPrintf( DEBUG_ERR, "%s: ciphertext is not aligned\n",
__func__);
return ERROR;
}
}
memset(&cryp, 0, sizeof(cryp));
/* Encrypt data.in to data.encrypted */
cryp.ses = ctx->sess.ses;
cryp.len = size;
cryp.src = (void*)plaintext;
cryp.dst = ciphertext;
cryp.iv = (void*)iv;
cryp.op = COP_ENCRYPT;
if (ioctl(ctx->cfd, CIOCCRYPT, &cryp)) {
DebugPrintf( DEBUG_ERR, "%s: ioctl(CIOCCRYPT)\n", __func__);
return ERROR;
}
return OK;
}
int aes_decrypt(struct cryptodev_ctx* ctx, const void* iv, const void*
ciphertext, void* plaintext, size_t size)
{
struct crypt_op cryp;
void* p;
/* check plaintext and ciphertext alignment */
if (ctx->alignmask) {
p = (void*)(((unsigned long)plaintext + ctx->alignmask) &
~ctx->alignmask);
if (plaintext != p) {
DebugPrintf( DEBUG_ERR, "%s: plaintext is not aligned\n",
__func__);
return ERROR;
}
p = (void*)(((unsigned long)ciphertext + ctx->alignmask) &
~ctx->alignmask);
if (ciphertext != p) {
DebugPrintf( DEBUG_ERR, "%s: ciphertext is not aligned\n",
__func__);
return ERROR;
}
}
memset(&cryp, 0, sizeof(cryp));
/* Decrypt ciphertext to plaintext */
cryp.ses = ctx->sess.ses;
cryp.len = size;
cryp.src = (void*)ciphertext;
cryp.dst = plaintext;
cryp.iv = (void*)iv;
cryp.op = COP_DECRYPT;
if (ioctl(ctx->cfd, CIOCCRYPT, &cryp)) {
DebugPrintf( DEBUG_ERR, "%s: ioctl(CIOCCRYPT)\n", __func__);
return ERROR;
}
return OK;
}
Thanks;
Bill Ross
|