Ich benutze Ocf-Linux in einer Openwrt-Anwendung und habe in OCF CRYPTO_MAX_DATA_LEN (64K-1) und E2BIG Fehler im CRYPTO_AES_CBC-Modus ausgeführt.ocf-linux, Aufteilen von großen Puffern in Stücke <MAX_DATA_LEN
Als Konsequenz muss ich den Eingabepuffer in Blöcke < MAX_DATA_LEN teilen und Chunks einzeln verarbeiten und die resultierenden Klartext/chiffrierten Textblöcke in einem großen Ausgabepuffer zusammenstellen.
Google hat spärliche Ergebnisse und keinen Code zu diesem Problem. Wikipedia zeigt dies möglich ist, durch die vorherige iv zum nächsten Block Betrieb Fütterung:
https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29
FRAGEN/POINT:
Ist das möglich ocf-linux mit?
Hat jemand dieses Problem gelöst/gelöst und hat (Pseudo-) Code = (Best Practice) zu teilen, um mich zu retten das Rad neu erfinden? 3 - Kann jemand irgendwelche Probleme mit meinem Code unten sehen?
Meine aktuelle decrypt Funktion (Arbeits für Größe < MAX_DATA_LEN) folgt:
Was ich beobachte falsche entschlüsselten Daten für alle ist, aber der erste Block mit dem Anfang iv. Ich vermute, dass nachfolgende ivs aus dem vorherigen Block irgendwie falsch sind, trotz der Verwendung des Algorithmus aus Wikipedia.
#define AES_CHUNK_SIZE 0xFFE0
#define IV_SIZE 128 // bits
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 (size <= CRYPTO_MAX_DATA_LEN) {
if (ioctl(ctx->cfd, CIOCCRYPT, &cryp)) {
DebugPrintf(DEBUG_ERR, "%s: ioctl(CIOCCRYPT)\n", __func__);
return ERROR;
}
} else {
unsigned int i, remainder;
cryp.len = AES_CHUNK_SIZE;
remainder = size % AES_CHUNK_SIZE;
char byte;
DebugPrintf(DEBUG_ERR, "%s: Decrypting large block AES_CHUNK_SIZE: %x size: %x remainder: %x\n",
__func__,
(unsigned int) AES_CHUNK_SIZE,
(unsigned int) size,
remainder);
for (i = 0; i < (size/AES_CHUNK_SIZE); i++) {
DebugPrintf(DEBUG_ERR, "%s: Decrypting chunk: %x\n", __func__, i);
if (ioctl(ctx->cfd, CIOCCRYPT, &cryp)) {
DebugPrintf(DEBUG_ERR, "%s: ioctl(CIOCCRYPT)\n", __func__);
return ERROR;
}
// Print first 32 bytes of decrypted chunk data
DebugPrintf(DEBUG_ERROR, "Decrypted data, Section offset: %x\n", (unsigned int) (AES_CHUNK_SIZE * i));
for (int j = 0; j < 32 ; j++) {
byte = cryp.dst[AES_CHUNK_SIZE * i + j];
DebugPrintf(DEBUG_ERROR, "%x ", byte);
}
DebugPrintf(DEBUG_ERROR, "\n");
cryp.src += AES_CHUNK_SIZE;
cryp.dst += AES_CHUNK_SIZE;
cryp.iv = cryp.src - (IV_SIZE/8);
}
if (remainder) {
DebugPrintf(DEBUG_ERR, "%s: Decrypting last chunk: %x\n", __func__, i);
cryp.len = remainder;
if (ioctl(ctx->cfd, CIOCCRYPT, &cryp)) {
DebugPrintf(DEBUG_ERR, "%s: ioctl(CIOCCRYPT)\n", __func__);
return ERROR;
}
DebugPrintf(DEBUG_ERROR, "Decrypted data, Section offset: %x\n", (unsigned int) (AES_CHUNK_SIZE * i));
for (int j = 0; j < 32 ; j++) {
byte = cryp.dst[AES_CHUNK_SIZE * i + j];
DebugPrintf(DEBUG_ERROR, "%x ", byte);
}
DebugPrintf(DEBUG_ERROR, "\n");
}
}
}
return OK;
}