Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
Cargo.lock
# Cargo lock in subs
**/Cargo.lock

# Generated by Cargo
**/target/
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ ring = "0.14.6"
quick-error = "1.2"
rust-crypto = "0.2.36"
primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" }
aes-gcm-siv = "0.3.0"
aead = "0.2.0"

[dev-dependencies]
rand = "0.6.1"
35 changes: 34 additions & 1 deletion src/aes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use aead::{generic_array::GenericArray, Aead, Error, NewAead};
use aes_gcm_siv::Aes256GcmSiv;
use primitives::H256;
use rcrypto::aes::KeySize::KeySize256;
use rcrypto::aes::{cbc_decryptor, cbc_encryptor};
Expand Down Expand Up @@ -69,6 +71,32 @@ pub fn decrypt(encrypted_data: &[u8], key: &H256, iv: &u128) -> Result<Vec<u8>,
Ok(final_result)
}

// AES-256/GCM/Pkcs encryption.
pub fn encrypt_gcm_siv(data: &[u8], key: &H256, nonce: &u128) -> Result<Vec<u8>, Error> {
let generic_key = GenericArray::clone_from_slice(key);
let aead = Aes256GcmSiv::new(generic_key);

let temp_nonce = &nonce.to_be_bytes();
let nonce = GenericArray::from_slice(&temp_nonce[0..12]);

Choose a reason for hiding this comment

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

Would you explain why do you take only 12 bytes from the nonce?

Copy link
Contributor Author

@somniumism somniumism Jan 29, 2020

Choose a reason for hiding this comment

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

@sgkim126 When using AES-GCM, a 96-bit IV is generally recommended. I referred to the following a answer. I think there is no problem with using only 12 bytes out of 16 bytes because we are using a fixed nonce.

Choose a reason for hiding this comment

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

If you will use only 12 bytes, IMHO, you should change the type of a nonce parameter as [u8: 12]. Discarding information inside a function may make the user misuse.

Copy link

Choose a reason for hiding this comment

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

Also, nonce reuse is not recommended in AES-GCM-SIV so we should not use a fixed nonce anymore.


let ciphertext = aead.encrypt(nonce, data).expect("encryption failure!");

Ok(ciphertext)
}

// AES-256/GCM/Pkcs decryption.
pub fn decrypt_gcm_siv(encrypted_data: &[u8], key: &H256, input_nonce: &u128) -> Result<Vec<u8>, Error> {
let generic_key = GenericArray::clone_from_slice(key);
let aead = Aes256GcmSiv::new(generic_key);

let bytes_nonce = &input_nonce.to_be_bytes();
let nonce = GenericArray::from_slice(&bytes_nonce[0..12]);

let plaintext = aead.decrypt(nonce, encrypted_data.as_ref()).expect("decryption failure!");

Ok(plaintext)
}

/// Encrypt a message (CTR mode).
///
/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each.
Expand Down Expand Up @@ -128,8 +156,10 @@ mod tests {

let encrypted_data = encrypt(message.as_bytes(), &key, &iv).ok().unwrap();
let decrypted_data = decrypt(&encrypted_data[..], &key, &iv).ok().unwrap();

let encrypted_data_with_gcm = encrypt_gcm_siv(message.as_bytes(), &key, &iv).ok().unwrap();
let decrypted_data_with_gcm = decrypt_gcm_siv(&encrypted_data_with_gcm[..], &key, &iv).ok().unwrap();
assert_eq!(message.as_bytes(), &decrypted_data[..]);
assert_eq!(message.as_bytes(), &decrypted_data_with_gcm[..]);
}

#[test]
Expand All @@ -144,6 +174,9 @@ mod tests {

let encrypted = encrypt(&input, &key, &iv).unwrap();
let decrypted = decrypt(&encrypted, &key, &iv).unwrap();
let encrypted_with_gcm = encrypt_gcm_siv(&input, &key, &iv).unwrap();
let decrypted_with_gcm = decrypt_gcm_siv(&encrypted_with_gcm, &key, &iv).unwrap();
assert_eq!(input, decrypted);
assert_eq!(input, decrypted_with_gcm);
}
}