diff --git a/cli/tests/unit_node/crypto/crypto_cipher_test.ts b/cli/tests/unit_node/crypto/crypto_cipher_test.ts index 846b56097ee7f8..7ea361bf6b31df 100644 --- a/cli/tests/unit_node/crypto/crypto_cipher_test.ts +++ b/cli/tests/unit_node/crypto/crypto_cipher_test.ts @@ -118,6 +118,16 @@ Deno.test({ "dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087", "0ac1d7e8655254c6814b46753932df88", ], + [ + ["aes256", 32, 16], + "dc95c078a2408989ad48a2149284208708c374848c228233c2b34f332bd2e9d38b70c515a6663d38cdb8e6532b266491", + "2e62607a5e8b715e4cb229a12169f2b2", + ], + [ + ["aes-256-cbc", 32, 16], + "dc95c078a2408989ad48a2149284208708c374848c228233c2b34f332bd2e9d38b70c515a6663d38cdb8e6532b266491", + "2e62607a5e8b715e4cb229a12169f2b2", + ], ] as const; for ( const [[alg, keyLen, ivLen], expectedUpdate, expectedFinal] of table @@ -186,6 +196,14 @@ Deno.test({ ["aes-256-ecb", 32, 0], "dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a214928420877c45b49560579dd1ffc7ec626de2a968", ], + [ + ["aes256", 32, 16], + "dc95c078a2408989ad48a2149284208708c374848c228233c2b34f332bd2e9d38b70c515a6663d38cdb8e6532b2664915d0dcc192580aee9ef8a8568193f1b44bfca557c6bab7dc79da07ffd42191b2659e6bee99cb2a6a7299f0e9a21686fc7", + ], + [ + ["aes-256-cbc", 32, 16], + "dc95c078a2408989ad48a2149284208708c374848c228233c2b34f332bd2e9d38b70c515a6663d38cdb8e6532b2664915d0dcc192580aee9ef8a8568193f1b44bfca557c6bab7dc79da07ffd42191b2659e6bee99cb2a6a7299f0e9a21686fc7", + ], ] as const; for ( const [[alg, keyLen, ivLen], input] of table diff --git a/ext/node/ops/crypto/cipher.rs b/ext/node/ops/crypto/cipher.rs index ce741ef01b621e..1072cc8c0fb1e1 100644 --- a/ext/node/ops/crypto/cipher.rs +++ b/ext/node/ops/crypto/cipher.rs @@ -25,7 +25,8 @@ enum Cipher { Aes256Ecb(Box>), Aes128Gcm(Box), Aes256Gcm(Box), - // TODO(kt3k): add more algorithms Aes192Cbc, Aes256Cbc, etc. + Aes256Cbc(Box>), + // TODO(kt3k): add more algorithms Aes192Cbc, etc. } enum Decipher { @@ -35,7 +36,8 @@ enum Decipher { Aes256Ecb(Box>), Aes128Gcm(Box), Aes256Gcm(Box), - // TODO(kt3k): add more algorithms Aes192Cbc, Aes256Cbc, Aes128GCM, etc. + Aes256Cbc(Box>), + // TODO(kt3k): add more algorithms Aes192Cbc, Aes128GCM, etc. } pub struct CipherContext { @@ -141,6 +143,9 @@ impl Cipher { Aes256Gcm(Box::new(cipher)) } + "aes256" | "aes-256-cbc" => { + Aes256Cbc(Box::new(cbc::Encryptor::new(key.into(), iv.into()))) + } _ => return Err(type_error(format!("Unknown cipher {algorithm_name}"))), }) } @@ -194,6 +199,12 @@ impl Cipher { output[..input.len()].copy_from_slice(input); cipher.encrypt(output); } + Aes256Cbc(encryptor) => { + assert!(input.len() % 16 == 0); + for (input, output) in input.chunks(16).zip(output.chunks_mut(16)) { + encryptor.encrypt_block_b2b_mut(input.into(), output.into()); + } + } } } @@ -228,6 +239,12 @@ impl Cipher { } Aes128Gcm(cipher) => Ok(Some(cipher.finish().to_vec())), Aes256Gcm(cipher) => Ok(Some(cipher.finish().to_vec())), + Aes256Cbc(encryptor) => { + let _ = (*encryptor) + .encrypt_padded_b2b_mut::(input, output) + .map_err(|_| type_error("Cannot pad the input data"))?; + Ok(None) + } } } } @@ -260,6 +277,9 @@ impl Decipher { Aes256Gcm(Box::new(decipher)) } + "aes256" | "aes-256-cbc" => { + Aes256Cbc(Box::new(cbc::Decryptor::new(key.into(), iv.into()))) + } _ => return Err(type_error(format!("Unknown cipher {algorithm_name}"))), }) } @@ -313,6 +333,12 @@ impl Decipher { output[..input.len()].copy_from_slice(input); decipher.decrypt(output); } + Aes256Cbc(decryptor) => { + assert!(input.len() % 16 == 0); + for (input, output) in input.chunks(16).zip(output.chunks_mut(16)) { + decryptor.decrypt_block_b2b_mut(input.into(), output.into()); + } + } } } @@ -369,6 +395,13 @@ impl Decipher { Err(type_error("Failed to authenticate data")) } } + Aes256Cbc(decryptor) => { + assert!(input.len() == 16); + let _ = (*decryptor) + .decrypt_padded_b2b_mut::(input, output) + .map_err(|_| type_error("Cannot unpad the input data"))?; + Ok(()) + } } } }