Data format for normal operation: +-------------+-------------+-------------+--------+--------+ | opType | len1 | len2 | param2 | param2 | | sizeof(int) | sizeof(int) | sizeof(int) | len1 | len2 | +-------------+-------------+-------------+--------+--------+ However, if the operation is encrypted: +-------------+-------------+-------------+---------------------------------+
| 466 | // +-----------------------------------------------------------------------------------------------------------+ |
| 467 | // |
| 468 | IDiskQueue::location log_op(OpType op, StringRef v1, StringRef v2) { |
| 469 | // Metadata op types to be excluded from encryption. |
| 470 | static std::unordered_set<OpType> metaOps = { OpSnapshotEnd, OpSnapshotAbort, OpCommit, OpRollback }; |
| 471 | if (!enableEncryption || metaOps.count(op) > 0) { |
| 472 | OpHeader h = { (int)op, v1.size(), v2.size() }; |
| 473 | log->push(StringRef((const uint8_t*)&h, sizeof(h))); |
| 474 | log->push(v1); |
| 475 | log->push(v2); |
| 476 | } else { |
| 477 | OpHeader h = { (int)OpEncrypted, v1.size(), v2.size() }; |
| 478 | log->push(StringRef((const uint8_t*)&h, sizeof(h))); |
| 479 | |
| 480 | uint8_t* plaintext = new uint8_t[sizeof(int) + v1.size() + v2.size()]; |
| 481 | *(int*)plaintext = op; |
| 482 | if (v1.size()) { |
| 483 | memcpy(plaintext + sizeof(int), v1.begin(), v1.size()); |
| 484 | } |
| 485 | if (v2.size()) { |
| 486 | memcpy(plaintext + sizeof(int) + v1.size(), v2.begin(), v2.size()); |
| 487 | } |
| 488 | |
| 489 | ASSERT(cipherKeys.cipherTextKey.isValid()); |
| 490 | ASSERT(cipherKeys.cipherHeaderKey.isValid()); |
| 491 | EncryptBlobCipherAes265Ctr cipher( |
| 492 | cipherKeys.cipherTextKey, cipherKeys.cipherHeaderKey, ENCRYPT_HEADER_AUTH_TOKEN_MODE_SINGLE); |
| 493 | BlobCipherEncryptHeader cipherHeader; |
| 494 | Arena arena; |
| 495 | StringRef ciphertext = |
| 496 | cipher.encrypt(plaintext, sizeof(int) + v1.size() + v2.size(), &cipherHeader, arena)->toStringRef(); |
| 497 | log->push(StringRef((const uint8_t*)&cipherHeader, BlobCipherEncryptHeader::headerSize)); |
| 498 | log->push(ciphertext); |
| 499 | } |
| 500 | return log->push(LiteralStringRef("\x01")); // Changes here should be reflected in OP_DISK_OVERHEAD |
| 501 | } |
| 502 | |
| 503 | // In case the op data is not encrypted, simply read the operands and the zero fill flag. |
| 504 | // Otherwise, decrypt the op type and data. |
no test coverage detected