[Ocf-linux-users] Splitting large buffers into chunks < MAX_DATA_LEN
Brought to you by:
david-m
|
From: Bill R. <ros...@gm...> - 2016-07-23 11:18:25
|
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 |