Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CBC mode refactor/improvements #124

Merged
merged 8 commits into from
Aug 29, 2024
10 changes: 10 additions & 0 deletions Primitive/Symmetric/Cipher/Block/Instantiations/AES128_CBC.cry
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Instantiate CBC mode for AES 128.
*
* @copyright Galois, Inc.
* @author Stanislav Lyakhov <stan@galois.com>
*/
module Primitive::Symmetric::Cipher::Block::Instantiations::AES128_CBC =
Primitive::Symmetric::Cipher::Block::Modes::CBC {
Primitive::Symmetric::Cipher::Block::AES128
}
10 changes: 10 additions & 0 deletions Primitive/Symmetric/Cipher/Block/Instantiations/AES192_CBC.cry
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Instantiate CBC mode for AES 192.
*
* @copyright Galois, Inc.
* @author Stanislav Lyakhov <stan@galois.com>
*/
module Primitive::Symmetric::Cipher::Block::Instantiations::AES192_CBC =
Primitive::Symmetric::Cipher::Block::Modes::CBC {
Primitive::Symmetric::Cipher::Block::AES192
}
10 changes: 10 additions & 0 deletions Primitive/Symmetric/Cipher/Block/Instantiations/AES256_CBC.cry
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Instantiate CBC mode for AES 256.
*
* @copyright Galois, Inc.
* @author Stanislav Lyakhov <stan@galois.com>
*/
module Primitive::Symmetric::Cipher::Block::Instantiations::AES256_CBC =
Primitive::Symmetric::Cipher::Block::Modes::CBC {
Primitive::Symmetric::Cipher::Block::AES256
}
73 changes: 0 additions & 73 deletions Primitive/Symmetric/Cipher/Block/Modes/AES128_CBC.cry

This file was deleted.

71 changes: 55 additions & 16 deletions Primitive/Symmetric/Cipher/Block/Modes/CBC.cry
Original file line number Diff line number Diff line change
@@ -1,21 +1,60 @@
// Cryptol CBC Implementation
// Copyright (c) 2010-2018, Galois Inc.
// www.cryptol.net
// Author: Ajay Kumar Eeralla
/*
* Cipher Block Chaining mode of operation, as defined in [NIST-SP-800-38A], Section 6.2.
*
* ⚠️ Warning ⚠️: CBC mode requires that the initialization vector (IV) is generated "unpredictably".
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CTR has a warning about not duplicating counters, so I figured I'd leave a warning about having unpredictable IVs here. Is that a good place to document such requirements?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, right now I'm in "throw warnings everywhere" mode, since there's no canonical approach. At the top of the file I like to list any differences we have with the spec (e.g. things it requires and we don't do, assumptions it makes that we can't satisfy, methods we've skipped for some reason etc.) with a flag for any that are security-critical, like this. I also like having them on the functions itself, like you did below.

* See Appendix C of [NIST-SP-800-38A] for discussion.
*
* @copyright Galois, Inc.
* @author Ajay Kumar Eeralla
* @author Marcella Hastings <marcella@galois.com>
* @author Stanislav Lyakhov <stan@galois.com>
* www.cryptol.net
*
* References:
* [NIST-SP-800-38A]: Morris Dworkin. Recommendation for Block Cipher
* Modes of Operation: Methods and Techniques. NIST Special Publication
* 800-38A. December 2001.
*
*/

module Primitive::Symmetric::Cipher::Block::Modes::CBC where

// set the sizes
type iv = [128]
type block = [128]

module Primitive::Symmetric::Cipher::Block::Modes::CBC where
import interface Primitive::Symmetric::Cipher::Block::CipherInterface as C

cbcEnc : {n, k} (fin n, fin k) => ([k]->block -> block) -> [k] -> iv -> [n]block -> [n]block
cbcEnc enc k iv ps = cs
where cs = [ enc k (p ^ c') | p <- ps | c' <- [iv] # cs ]
/**
* CBC encryption: [NIST-SP-800-38A] Section 6.2.
*
* Parameters: key, initialization vector, plaintext
*
* ⚠️ Warning ⚠️: CBC mode requires that the initialization vector (IV) is generated "unpredictably".
marsella marked this conversation as resolved.
Show resolved Hide resolved
* See Appendix C of [NIST-SP-800-38A] for discussion.
*/
encrypt : {n} (fin n) => [C::KeySize] -> [C::BlockSize] -> [n][C::BlockSize] -> [n][C::BlockSize]
marsella marked this conversation as resolved.
Show resolved Hide resolved
encrypt k iv ps = cs
where
ciph_k = C::encrypt k
cs = [ ciph_k (p_j ^ c') | p_j <- ps | c' <- [iv] # cs]

cbcDec : {n, k} (fin n, fin k) => ([k]->block -> block) -> [k] -> iv -> [n]block -> [n]block
cbcDec dec k iv cs = [ (dec k c) ^ c' | c <- cs | c' <- [iv] # cs ]
/**
* CBC decryption: [NIST-SP-800-38A] Section 6.2.
*
* Parameters: key, initialization vector, ciphertext
*
* ⚠️ Warning ⚠️: CBC mode requires that the initialization vector (IV) is generated "unpredictably".
* See Appendix C of [NIST-SP-800-38A] for discussion.
*/
decrypt : {n} (fin n) => [C::KeySize] -> [C::BlockSize] -> [n][C::BlockSize] -> [n][C::BlockSize]
decrypt k iv cs = ps
where
ciph_inv_k = C::decrypt k
ps = [ (ciph_inv_k c) ^ c' | c <- cs | c' <- [iv] # cs]

// This will need to be parameterized with a specific encryption function before it can be proved
property cbcEncCorrect encrypt k c ps = (cbcDec encrypt k c (cbcEnc encrypt k c ps)) == ps
/**
* Decryption must be the inverse of encryption.
* With high probability, this will be incredibly slow to prove.
* ```repl
* :check encryptCorrect`{n=5}
* ```
*/
encryptCorrect : {n} (fin n) => [C::KeySize] -> [C::BlockSize] -> [n][C::BlockSize] -> Bool
property encryptCorrect k iv ps = (decrypt k iv (encrypt k iv ps)) == ps
139 changes: 139 additions & 0 deletions Primitive/Symmetric/Cipher/Block/Tests/TestAES_CBC.cry
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Test vectors for AES-CBC mode.
* These are taken from [NIST-SP-800-38A] Appendix F.2
*
* @copyright Galois, Inc.
* @author Ajay Kumar Eeralla
* @author Marcella Hastings <marcella@galois.com>
* @author Stanislav Lyakhov <stan@galois.com>
* www.cryptol.net
*
* References:
* [NIST-SP-800-38A]: Morris Dworkin. Recommendation for Block Cipher
* Modes of Operation: Methods and Techniques. NIST Special Publication
* 800-38A. December 2001.
marsella marked this conversation as resolved.
Show resolved Hide resolved
*
*/
import Primitive::Symmetric::Cipher::Block::Instantiations::AES128_CBC as AES128_CBC
import Primitive::Symmetric::Cipher::Block::Instantiations::AES192_CBC as AES192_CBC
import Primitive::Symmetric::Cipher::Block::Instantiations::AES256_CBC as AES256_CBC

/**
* ```repl
* :prove aes128_cbc_encrypt_vector
* ```
*/
property aes128_cbc_encrypt_vector = (AES128_CBC::encrypt k iv plaintext) == ciphertext
staslyakhov marked this conversation as resolved.
Show resolved Hide resolved
where
k = 0x2b7e151628aed2a6abf7158809cf4f3c
iv = 0x000102030405060708090a0b0c0d0e0f
plaintext = [
0x6bc1bee22e409f96e93d7e117393172a,
0xae2d8a571e03ac9c9eb76fac45af8e51,
0x30c81c46a35ce411e5fbc1191a0a52ef,
0xf69f2445df4f9b17ad2b417be66c3710]
ciphertext = [
0x7649abac8119b246cee98e9b12e9197d,
0x5086cb9b507219ee95db113a917678b2,
0x73bed6b8e3c1743b7116e69e22229516,
0x3ff1caa1681fac09120eca307586e1a7]

/**
* ```repl
* :prove aes128_cbc_decrypt_vector
* ```
*/
property aes128_cbc_decrypt_vector = (AES128_CBC::decrypt k iv ciphertext) == plaintext
where
k = 0x2b7e151628aed2a6abf7158809cf4f3c
iv = 0x000102030405060708090a0b0c0d0e0f
ciphertext = [
0x7649abac8119b246cee98e9b12e9197d,
0x5086cb9b507219ee95db113a917678b2,
0x73bed6b8e3c1743b7116e69e22229516,
0x3ff1caa1681fac09120eca307586e1a7]
plaintext = [
0x6bc1bee22e409f96e93d7e117393172a,
0xae2d8a571e03ac9c9eb76fac45af8e51,
0x30c81c46a35ce411e5fbc1191a0a52ef,
0xf69f2445df4f9b17ad2b417be66c3710]

/**
* ```repl
* :prove aes192_cbc_encrypt_vector
* ```
*/
property aes192_cbc_encrypt_vector = (AES192_CBC::encrypt k iv plaintext) == ciphertext
where
k = 0x8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b
iv = 0x000102030405060708090a0b0c0d0e0f
plaintext = [
0x6bc1bee22e409f96e93d7e117393172a,
0xae2d8a571e03ac9c9eb76fac45af8e51,
0x30c81c46a35ce411e5fbc1191a0a52ef,
0xf69f2445df4f9b17ad2b417be66c3710]
ciphertext = [
0x4f021db243bc633d7178183a9fa071e8,
0xb4d9ada9ad7dedf4e5e738763f69145a,
0x571b242012fb7ae07fa9baac3df102e0,
0x08b0e27988598881d920a9e64f5615cd]

/**
* ```repl
* :prove aes192_cbc_decrypt_vector
* ```
*/
property aes192_cbc_decrypt_vector = (AES192_CBC::decrypt k iv ciphertext) == plaintext
where
k = 0x8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b
iv = 0x000102030405060708090a0b0c0d0e0f
ciphertext = [
0x4f021db243bc633d7178183a9fa071e8,
0xb4d9ada9ad7dedf4e5e738763f69145a,
0x571b242012fb7ae07fa9baac3df102e0,
0x08b0e27988598881d920a9e64f5615cd]
plaintext = [
0x6bc1bee22e409f96e93d7e117393172a,
0xae2d8a571e03ac9c9eb76fac45af8e51,
0x30c81c46a35ce411e5fbc1191a0a52ef,
0xf69f2445df4f9b17ad2b417be66c3710]

/**
* ```repl
* :prove aes256_cbc_encrypt_vector
* ```
*/
property aes256_cbc_encrypt_vector = (AES256_CBC::encrypt k iv plaintext) == ciphertext
where
k = 0x603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4
iv = 0x000102030405060708090a0b0c0d0e0f
plaintext = [
0x6bc1bee22e409f96e93d7e117393172a,
0xae2d8a571e03ac9c9eb76fac45af8e51,
0x30c81c46a35ce411e5fbc1191a0a52ef,
0xf69f2445df4f9b17ad2b417be66c3710]
ciphertext = [
0xf58c4c04d6e5f1ba779eabfb5f7bfbd6,
0x9cfc4e967edb808d679f777bc6702c7d,
0x39f23369a9d9bacfa530e26304231461,
0xb2eb05e2c39be9fcda6c19078c6a9d1b]

/**
* ```repl
* :prove aes256_cbc_decrypt_vector
* ```
*/
property aes256_cbc_decrypt_vector = (AES256_CBC::decrypt k iv ciphertext) == plaintext
where
k = 0x603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4
iv = 0x000102030405060708090a0b0c0d0e0f
ciphertext = [
0xf58c4c04d6e5f1ba779eabfb5f7bfbd6,
0x9cfc4e967edb808d679f777bc6702c7d,
0x39f23369a9d9bacfa530e26304231461,
0xb2eb05e2c39be9fcda6c19078c6a9d1b]
plaintext = [
0x6bc1bee22e409f96e93d7e117393172a,
0xae2d8a571e03ac9c9eb76fac45af8e51,
0x30c81c46a35ce411e5fbc1191a0a52ef,
0xf69f2445df4f9b17ad2b417be66c3710]