From 7184de2b5dd729bcbf5a6e53feb872cc3c4a1452 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 26 Aug 2013 18:33:42 +0000 Subject: Support 64 and 96 bit tags in OCB, using the nonce formatting rule added in the latest CFRG internet draft. --- checks/ocb.cpp | 149 +++++++++++---------------------------------------------- 1 file changed, 29 insertions(+), 120 deletions(-) (limited to 'checks') diff --git a/checks/ocb.cpp b/checks/ocb.cpp index abd84df7a..5cf6d9296 100644 --- a/checks/ocb.cpp +++ b/checks/ocb.cpp @@ -11,41 +11,51 @@ using namespace Botan; // something like this should be in the library -std::vector ocb_encrypt(const SymmetricKey& key, + +std::vector ocb_decrypt(const SymmetricKey& key, const std::vector& nonce, - const byte pt[], size_t pt_len, + const byte ct[], size_t ct_len, const byte ad[], size_t ad_len) { - //std::unique_ptr ocb = get_aead("AES-128/OCB", ENCRYPTION); - - OCB_Encryption ocb(new AES_128); + OCB_Decryption ocb(new AES_128); ocb.set_key(key); ocb.set_associated_data(ad, ad_len); ocb.start(&nonce[0], nonce.size()); - secure_vector buf(pt, pt+pt_len); + secure_vector buf(ct, ct+ct_len); ocb.finish(buf, 0); return unlock(buf); } -std::vector ocb_decrypt(const SymmetricKey& key, +std::vector ocb_encrypt(const SymmetricKey& key, const std::vector& nonce, - const byte ct[], size_t ct_len, + const byte pt[], size_t pt_len, const byte ad[], size_t ad_len) { - OCB_Decryption ocb(new AES_128); + OCB_Encryption ocb(new AES_128); ocb.set_key(key); ocb.set_associated_data(ad, ad_len); ocb.start(&nonce[0], nonce.size()); - secure_vector buf(ct, ct+ct_len); + secure_vector buf(pt, pt+pt_len); ocb.finish(buf, 0); + try + { + std::vector pt2 = ocb_decrypt(key, nonce, &buf[0], buf.size(), ad, ad_len); + if(pt_len != pt2.size() || !same_mem(pt, &pt2[0], pt_len)) + std::cout << "OCB failed to decrypt correctly\n"; + } + catch(std::exception& e) + { + std::cout << "OCB round trip error - " << e.what() << "\n"; + } + return unlock(buf); } @@ -82,13 +92,11 @@ std::vector ocb_encrypt(OCB_Encryption& ocb, return unlock(buf); } -void test_ocb_long_filters() +void test_ocb_long(size_t taglen, const std::string &expected) { - SymmetricKey key("00000000000000000000000000000000"); + OCB_Encryption ocb(new AES_128, taglen/8); - OCB_Encryption ocb(new AES_128); - - ocb.set_key(key); + ocb.set_key(SymmetricKey("00000000000000000000000000000000")); const std::vector empty; std::vector N(12); @@ -99,120 +107,20 @@ void test_ocb_long_filters() const std::vector S(i); N[11] = i; - const std::vector C1 = ocb_encrypt(ocb, N, S, S); - const std::vector C2 = ocb_encrypt(ocb, N, S, empty); - const std::vector C3 = ocb_encrypt(ocb, N, empty, S); - - //std::cout << "C_" << i << " = " << hex_encode(C1) << " " << hex_encode(C2) << " " << hex_encode(C3) << "\n"; - - C += C1; - C += C2; - C += C3; + C += ocb_encrypt(ocb, N, S, S); + C += ocb_encrypt(ocb, N, S, empty); + C += ocb_encrypt(ocb, N, empty, S); } - SHA_256 sha256; - sha256.update(C); - const std::string C_hash = hex_encode(sha256.final()); - const std::string expected_C_hash = "C4E5158067F49356042296B13B050DE00A120EA846073E5E0DACFD0C9F43CC65"; - - if(C_hash != expected_C_hash) - { - std::cout << "OCB-128 long test, C hashes differ\n"; - std::cout << C_hash << " !=\n" << expected_C_hash << "\n"; - } - - //std::cout << "SHA-256(C) = " << C_hash << "\n"; - N[11] = 0; const std::vector cipher = ocb_encrypt(ocb, N, empty, C); - const std::string expected = "B2B41CBF9B05037DA7F16C24A35C1C94"; - - const std::string cipher_hex = hex_encode(cipher); - - if(cipher_hex != expected) - std::cout << "OCB AES-128 long test mistmatch " << cipher_hex << " != " << expected << "\n"; - else - std::cout << "OCB AES-128 long test OK\n"; - } - -void test_ocb_long() - { - SymmetricKey key("00000000000000000000000000000000"); - - const std::vector empty; - std::vector N(12); - std::vector C; - - for(size_t i = 0; i != 128; ++i) - { - const std::vector S(i); - N[11] = i; - - const std::vector C1 = ocb_encrypt(key, N, S, S); - const std::vector C2 = ocb_encrypt(key, N, S, empty); - const std::vector C3 = ocb_encrypt(key, N, empty, S); - - //std::cout << "C_" << i << " = " << hex_encode(C1) << " " << hex_encode(C2) << " " << hex_encode(C3) << "\n"; - - C += C1; - C += C2; - C += C3; - - SHA_256 sha256; - sha256.update(C); - //std::cout << "SHA-256(C_" << i << ") = " << hex_encode(sha256.final()) << "\n"; - } - - // SHA-256 hash of C would be useful - - SHA_256 sha256; - sha256.update(C); - const std::string C_hash = hex_encode(sha256.final()); - const std::string expected_C_hash = "C4E5158067F49356042296B13B050DE00A120EA846073E5E0DACFD0C9F43CC65"; - - if(C_hash != expected_C_hash) - { - std::cout << "OCB-128 long test, C hashes differ\n"; - std::cout << C_hash << " !=\n" << expected_C_hash << "\n"; - } - - //std::cout << "SHA-256(C) = " << C_hash << "\n"; - - N[11] = 0; - const std::vector cipher = ocb_encrypt(key, N, empty, C); - - const std::string expected = "B2B41CBF9B05037DA7F16C24A35C1C94"; - const std::string cipher_hex = hex_encode(cipher); if(cipher_hex != expected) std::cout << "OCB AES-128 long test mistmatch " << cipher_hex << " != " << expected << "\n"; else std::cout << "OCB AES-128 long test OK\n"; - - try - { - const std::vector p = ocb_decrypt(key, N, cipher, C); - - BOTAN_ASSERT(p.empty(), "return plaintext is empty"); - } - catch(std::exception& e) - { - std::cout << "Error in OCB decrypt - " << e.what() << "\n"; - } - - try - { - C[0] ^= 1; - ocb_decrypt(key, N, cipher, C); - std::cout << "OCB failed to reject bad message\n"; - } - catch(std::exception& e) - { - } - - } void test_ocb() @@ -247,8 +155,9 @@ void test_ocb() std::cout << "Correct OCB message rejected - " << e.what() << "\n"; } - //test_ocb_long(); - test_ocb_long_filters(); + test_ocb_long(128, "B2B41CBF9B05037DA7F16C24A35C1C94"); + test_ocb_long(96, "1A4F0654277709A5BDA0D380"); + test_ocb_long(64, "B7ECE9D381FE437F"); } -- cgit v1.2.3