diff --git a/Cargo.lock b/Cargo.lock index 46308c784..4274dc022 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,9 +33,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bindgen" @@ -308,13 +308,14 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] name = "mbedtls" -version = "0.7.1" +version = "0.7.2" dependencies = [ "bit-vec", "bitflags", "block-modes", "byteorder", "cc", + "cfg-if 1.0.0", "chrono", "core_io", "hex", @@ -631,11 +632,10 @@ dependencies = [ [[package]] name = "tokio" -version = "0.3.7" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46409491c9375a693ce7032101970a54f8a2010efb77e13f70788f0d84489e39" +checksum = "0c27a64b625de6d309e8c57716ba93021dccf1b3b5c97edd6d3dd2d2135afc0a" dependencies = [ - "autocfg", "pin-project-lite", ] diff --git a/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index a8ee861b7..d83b3f43e 100644 --- a/mbedtls/Cargo.toml +++ b/mbedtls/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mbedtls" -version = "0.7.1" +version = "0.7.2" authors = ["Jethro Beekman "] build = "build.rs" edition = "2018" @@ -30,7 +30,7 @@ num-bigint = { version = "0.2", optional = true } bit-vec = { version = "0.5", optional = true } block-modes = { version = "0.3", optional = true } rc2 = { version = "0.3", optional = true } -tokio = { version = "0.3", optional = true } +tokio = { version = "1.16.1", optional = true } proc-macro2 = "=1.0.24" quote = "=1.0.9" @@ -48,6 +48,7 @@ rand = "0.4.0" serde_cbor = "0.6" hex = "0.3" matches = "0.1.8" +cfg-if = "1.0.0" [build-dependencies] cc = "1.0" diff --git a/mbedtls/src/cipher/raw/mod.rs b/mbedtls/src/cipher/raw/mod.rs index c39563018..c6d883814 100644 --- a/mbedtls/src/cipher/raw/mod.rs +++ b/mbedtls/src/cipher/raw/mod.rs @@ -23,6 +23,7 @@ define!( Camellia = CIPHER_ID_CAMELLIA, Blowfish = CIPHER_ID_BLOWFISH, Arc4 = CIPHER_ID_ARC4, + Aria = CIPHER_ID_ARIA, } ); @@ -37,6 +38,7 @@ impl From for CipherId { CIPHER_ID_CAMELLIA => CipherId::Camellia, CIPHER_ID_BLOWFISH => CipherId::Blowfish, CIPHER_ID_ARC4 => CipherId::Arc4, + CIPHER_ID_ARIA => CipherId::Aria, // This should be replaced with TryFrom once it is stable. _ => panic!("Invalid cipher_id_t"), } diff --git a/mbedtls/src/cipher/raw/serde.rs b/mbedtls/src/cipher/raw/serde.rs index 7cb018996..6bb621301 100644 --- a/mbedtls/src/cipher/raw/serde.rs +++ b/mbedtls/src/cipher/raw/serde.rs @@ -44,6 +44,7 @@ pub struct SavedRawCipher { #[derive(Serialize, Deserialize)] enum AlgorithmContext { Aes(Bytes), + Aria(Bytes), Des(Bytes), Des3(Bytes), Gcm { @@ -94,6 +95,12 @@ unsafe fn serialize_raw_cipher(mut cipher_context: cipher_context_t) aes_context.rk = ::core::ptr::null_mut(); AlgorithmContext::Aes(Bytes(aes_context)) } + (CIPHER_ID_ARIA, MODE_CBC) + | (CIPHER_ID_ARIA, MODE_CTR) + | (CIPHER_ID_ARIA, MODE_CFB) + | (CIPHER_ID_ARIA, MODE_ECB) => { + AlgorithmContext::Aria(Bytes(*(cipher_context.cipher_ctx as *const aria_context))) + } (CIPHER_ID_DES, MODE_CBC) | (CIPHER_ID_DES, MODE_CTR) | (CIPHER_ID_DES, MODE_CFB) => { @@ -208,6 +215,9 @@ unsafe fn deserialize_raw_cipher(raw: SavedRawCipher, padding: raw::CipherPaddin // mbedtls_aes_context in the mbedTLS source). (*ret_aes_ctx).rk = &mut (*ret_aes_ctx).buf[0]; } + (CIPHER_ID_ARIA, AlgorithmContext::Aria(Bytes(aria_ctx))) => { + *(cipher_context.cipher_ctx as *mut aria_context) = aria_ctx + } (CIPHER_ID_DES, AlgorithmContext::Des(Bytes(des_ctx))) => { *(cipher_context.cipher_ctx as *mut des_context) = des_ctx } @@ -321,6 +331,7 @@ impl<'de, T: BytesSerde> Deserialize<'de> for Bytes { unsafe impl BytesSerde for cipher_context_t {} unsafe impl BytesSerde for aes_context {} +unsafe impl BytesSerde for aria_context {} unsafe impl BytesSerde for des_context {} unsafe impl BytesSerde for des3_context {} unsafe impl BytesSerde for gcm_context {} diff --git a/mbedtls/src/ecp/mod.rs b/mbedtls/src/ecp/mod.rs index 8d28dcac8..8a675a33b 100644 --- a/mbedtls/src/ecp/mod.rs +++ b/mbedtls/src/ecp/mod.rs @@ -79,6 +79,13 @@ impl EcGroup { Ok(ret) } + /// Initialize an EcGroup with custom group parameters. + /// + /// HAZMAT: This function DOES NOT perform a full check on parameters + /// against all known attacks. The caller MUST make sure that parameters are + /// trusted. Failing to comply with this requirement may result in the use + /// of INSECURE curves. Prefer [EcGroup::new] with known curves listed in + /// [EcGroupId]. pub fn from_parameters( p: Mpi, a: Mpi, @@ -96,15 +103,16 @@ impl EcGroup { let zero = Mpi::new(0)?; // basic bounds checking - if &a <= &zero + if &a < &zero || &a >= &p - || &b <= &zero + || &b < &zero || &b >= &p - || &g_x <= &zero + || &g_x < &zero || &g_x >= &p - || &g_y <= &zero + || &g_y < &zero || &g_y >= &p || &order <= &zero + || (&a == &zero && &b == &zero) { return Err(Error::EcpBadInputData); } @@ -191,6 +199,8 @@ impl EcGroup { match self.group_id()? { EcGroupId::Curve25519 => Ok(8), EcGroupId::Curve448 => Ok(4), + // Requires a point-counting algorithm such as SEA. + EcGroupId::None => Err(Error::EcpFeatureUnavailable), _ => Ok(1), } } @@ -754,4 +764,154 @@ mod tests { let pt3 = pt1.clone(); assert_eq!(pt2.eq(&pt3).unwrap(), true); } + + #[cfg(feature = "std")] + struct Params<'a> { + p: &'a str, + a: &'a str, + b: &'a str, + g_x: &'a str, + g_y: &'a str, + n: &'a str, + } + + #[cfg(feature = "std")] + impl Into> for Params<'_> { + fn into(self) -> super::Result { + use std::str::FromStr; + EcGroup::from_parameters( + Mpi::from_str(self.p)?, + Mpi::from_str(self.a)?, + Mpi::from_str(self.b)?, + Mpi::from_str(self.g_x)?, + Mpi::from_str(self.g_y)?, + Mpi::from_str(self.n)?, + ) + } + } + + #[test] + #[cfg(feature = "std")] + fn pathological_parameters() { + // y² = x³ mod 7 (note a == b == 0) + let singular: super::Result<_> = Params { + p: "0x07", + a: "0x00", + b: "0x00", + g_x: "0x01", + g_y: "0x02", + n: "0x0b", + }.into(); + assert!(singular.is_err()); + } + + #[test] + #[cfg(feature = "std")] + fn bad_generators() { + // y² = x³ + x + 6 (mod 7) with bad generator (1, 2) and prime order 11 + let small_curve: super::Result<_> = Params { + p: "0x07", + a: "0x01", + b: "0x06", + g_x: "0x01", + g_y: "0x02", + n: "0x0b", + }.into(); + assert!(small_curve.is_err()); + + // y² = x³ + x + 6 (mod 7) with bad generator (0, 0) and prime order 11 + let small_curve_zero_gen: super::Result<_> = Params { + p: "0x07", + a: "0x01", + b: "0x06", + g_x: "0x00", + g_y: "0x00", + n: "0x0b", + }.into(); + assert!(small_curve_zero_gen.is_err()); + } + + #[test] + #[cfg(feature = "std")] + fn unknown_cofactor() { + // y² = x³ + x + 6 (mod 7) with generator (1, 6) and prime order 11 + let small_curve: super::Result<_> = Params { + p: "0x07", + a: "0x01", + b: "0x06", + g_x: "0x01", + g_y: "0x06", + n: "0x0b", + }.into(); + assert!(small_curve.unwrap().cofactor().is_err()); + } + + #[test] + #[cfg(feature = "std")] + fn zero_params_curves() { + use super::Result; + // Barreto-Naehrig 254, note a = 0 + let bn254: Result<_> = Params { + p: "0x2523648240000001BA344D80000000086121000000000013A700000000000013", + a: "0x0000000000000000000000000000000000000000000000000000000000000000", + b: "0x0000000000000000000000000000000000000000000000000000000000000002", + g_x: "0x2523648240000001BA344D80000000086121000000000013A700000000000012", + g_y: "0x0000000000000000000000000000000000000000000000000000000000000001", + n: "0x2523648240000001BA344D8000000007FF9F800000000010A10000000000000D", + }.into(); + assert!(bn254.is_ok()); + + // Prescribed embedded degree of 12, BLS12-381 + let bls12_381: Result<_> = Params { + p: "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", + a: "0x00", + b: "0x04", + g_x: "0x17F1D3A73197D7942695638C4FA9AC0FC3688C4F9774B905A14E3A3F171BAC586C55E83FF97A1AEFFB3AF00ADB22C6BB", + g_y: "0x08B3F481E3AAA0F1A09E30ED741D8AE4FCF5E095D5D00AF600DB18CB2C04B3EDD03CC744A2888AE40CAA232946C5E7E1", + n: "0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001", + }.into(); + assert!(bls12_381.is_ok()); + + // Fp256BN + let fp256_bn: Result<_> = Params { + p: "0xfffffffffffcf0cd46e5f25eee71a49f0cdc65fb12980a82d3292ddbaed33013", + a: "0x00", + b: "0x03", + g_x: "0x01", + g_y: "0x02", + n: "0xfffffffffffcf0cd46e5f25eee71a49e0cdc65fb1299921af62d536cd10b500d", + }.into(); + assert!(fp256_bn.is_ok()); + + // id-GostR3410-2001-CryptoPro-C-ParamSet, note g_x = 0 + let gost_r3410: Result<_> = Params { + p: "0x9b9f605f5a858107ab1ec85e6b41c8aacf846e86789051d37998f7b9022d759b", + a: "0x9b9f605f5a858107ab1ec85e6b41c8aacf846e86789051d37998f7b9022d7598", + b: "0x805a", + g_x: "0x00", + g_y: "0x41ece55743711a8c3cbf3783cd08c0ee4d4dc440d4641a8f366e550dfdb3bb67", + n: "0x9b9f605f5a858107ab1ec85e6b41c8aa582ca3511eddfb74f02f3a6598980bb9", + }.into(); + assert!(gost_r3410.is_ok()); + + // secp256k1 (Bitcoin), note a = 0 + let my_secp256k1: Result = Params { + p: "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + a: "0x0000000000000000000000000000000000000000000000000000000000000000", + b: "0x0000000000000000000000000000000000000000000000000000000000000007", + g_x: "0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + g_y: "0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + n: "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + }.into(); + assert!(my_secp256k1.is_ok()); + let my_secp256k1 = my_secp256k1.unwrap(); + + // We compare against the known SecP256K1 + let secp256k1 = EcGroup::new(EcGroupId::SecP256K1).unwrap(); + assert!(my_secp256k1.p() == secp256k1.p()); + assert!(my_secp256k1.a() == secp256k1.a()); + assert!(my_secp256k1.b() == secp256k1.b()); + assert!(my_secp256k1.generator() == secp256k1.generator()); + assert!(my_secp256k1.order() == secp256k1.order()); + } } diff --git a/mbedtls/src/hash/mod.rs b/mbedtls/src/hash/mod.rs index 64dbaa9b4..38b975e30 100644 --- a/mbedtls/src/hash/mod.rs +++ b/mbedtls/src/hash/mod.rs @@ -147,6 +147,29 @@ impl Md { Ok(olen) } } + + pub fn hkdf(md: Type, salt: &[u8], ikm: &[u8], info: &[u8], key: &mut [u8]) -> Result<()> { + let md: MdInfo = match md.into() { + Some(md) => md, + None => return Err(Error::MdBadInputData), + }; + + unsafe { + hkdf( + md.inner, + salt.as_ptr(), + salt.len(), + ikm.as_ptr(), + ikm.len(), + info.as_ptr(), + info.len(), + key.as_mut_ptr(), + key.len(), + ) + .into_result()?; + Ok(()) + } + } } pub fn pbkdf2_hmac( diff --git a/mbedtls/src/self_test.rs b/mbedtls/src/self_test.rs index 3a97b2244..2f3b214fa 100644 --- a/mbedtls/src/self_test.rs +++ b/mbedtls/src/self_test.rs @@ -59,7 +59,7 @@ pub unsafe fn disable() { } pub use mbedtls_sys::{ - aes_self_test as aes, arc4_self_test as arc4, base64_self_test as base64, + aes_self_test as aes, arc4_self_test as arc4, aria_self_test as aria, base64_self_test as base64, camellia_self_test as camellia, ccm_self_test as ccm, ctr_drbg_self_test as ctr_drbg, des_self_test as des, dhm_self_test as dhm, ecjpake_self_test as ecjpake, ecp_self_test as ecp, entropy_self_test as entropy, gcm_self_test as gcm, hmac_drbg_self_test as hmac_drbg, diff --git a/mbedtls/src/ssl/ciphersuites.rs b/mbedtls/src/ssl/ciphersuites.rs index 20cbeaac8..8bd193a33 100644 --- a/mbedtls/src/ssl/ciphersuites.rs +++ b/mbedtls/src/ssl/ciphersuites.rs @@ -120,6 +120,44 @@ define!( EcdhePskWithNullSha = TLS_ECDHE_PSK_WITH_NULL_SHA, EcdhePskWithNullSha256 = TLS_ECDHE_PSK_WITH_NULL_SHA256, EcdhePskWithNullSha384 = TLS_ECDHE_PSK_WITH_NULL_SHA384, + RsaWithAria128CbcSha256 = TLS_RSA_WITH_ARIA_128_CBC_SHA256, + RsaWithAria256CbcSha384 = TLS_RSA_WITH_ARIA_256_CBC_SHA384, + DheRsaWithAria128CbcSha256 = TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, + DheRsaWithAria256CbcSha384 = TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, + EcdheEcdsaWithAria128CbcSha256 = TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, + EcdheEcdsaWithAria256CbcSha384 = TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, + EcdhEcdsaWithAria128CbcSha256 = TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, + EcdhEcdsaWithAria256CbcSha384 = TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, + EcdheRsaWithAria128CbcSha256 = TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, + EcdheRsaWithAria256CbcSha384 = TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, + EcdhRsaWithAria128CbcSha256 = TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, + EcdhRsaWithAria256CbcSha384 = TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, + RsaWithAria128GcmSha256 = TLS_RSA_WITH_ARIA_128_GCM_SHA256, + RsaWithAria256GcmSha384 = TLS_RSA_WITH_ARIA_256_GCM_SHA384, + DheRsaWithAria128GcmSha256 = TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, + DheRsaWithAria256GcmSha384 = TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, + EcdheEcdsaWithAria128GcmSha256 = TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, + EcdheEcdsaWithAria256GcmSha384 = TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, + EcdhEcdsaWithAria128GcmSha256 = TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, + EcdhEcdsaWithAria256GcmSha384 = TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, + EcdheRsaWithAria128GcmSha256 = TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, + EcdheRsaWithAria256GcmSha384 = TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, + EcdhRsaWithAria128GcmSha256 = TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, + EcdhRsaWithAria256GcmSha384 = TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, + PskWithAria128CbcSha256 = TLS_PSK_WITH_ARIA_128_CBC_SHA256, + PskWithAria256CbcSha384 = TLS_PSK_WITH_ARIA_256_CBC_SHA384, + DhePskWithAria128CbcSha256 = TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, + DhePskWithAria256CbcSha384 = TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, + RsaPskWithAria128CbcSha256 = TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, + RsaPskWithAria256CbcSha384 = TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384, + PskWithAria128GcmSha256 = TLS_PSK_WITH_ARIA_128_GCM_SHA256, + PskWithAria256GcmSha384 = TLS_PSK_WITH_ARIA_256_GCM_SHA384, + DhePskWithAria128GcmSha256 = TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, + DhePskWithAria256GcmSha384 = TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, + RsaPskWithAria128GcmSha256 = TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, + RsaPskWithAria256GcmSha384 = TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, + EcdhePskWithAria128CbcSha256 = TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, + EcdhePskWithAria256CbcSha384 = TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, EcdheEcdsaWithCamellia128CbcSha256 = TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, EcdheEcdsaWithCamellia256CbcSha384 = TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, EcdhEcdsaWithCamellia128CbcSha256 = TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, diff --git a/mbedtls/tests/hkdf.rs b/mbedtls/tests/hkdf.rs new file mode 100644 index 000000000..e39c9f379 --- /dev/null +++ b/mbedtls/tests/hkdf.rs @@ -0,0 +1,34 @@ +/* Copyright (c) Fortanix, Inc. + * + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except + * according to those terms. */ + +use mbedtls::hash::Md; +use mbedtls::hash::Type as MdType; + +#[test] +fn test_hkdf_sha256() { + let ikm = [ + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + ]; + + let salt = [ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + ]; + let info = [0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9]; + let mut output = [0u8; 42]; + Md::hkdf(MdType::Sha256, &salt, &ikm, &info, &mut output).unwrap(); + + assert_eq!( + output, + [ + 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, + 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, + 0xec, 0xc4, 0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65 + ] + ); +} diff --git a/mbedtls/tests/mbedtls_self_tests.rs b/mbedtls/tests/mbedtls_self_tests.rs index 0b74eb572..dbac4e443 100644 --- a/mbedtls/tests/mbedtls_self_tests.rs +++ b/mbedtls/tests/mbedtls_self_tests.rs @@ -25,6 +25,16 @@ fn enable_self_test() { static START: Once = Once::new(); + let _log_f: Option; + + cfg_if::cfg_if! { + if #[cfg(feature = "std")] { + _log_f = None; + } else { + _log_f = Some(log as _); + } + } + START.call_once(|| { // safe because synchronized unsafe { mbedtls::self_test::enable(rand, log) }; @@ -52,6 +62,7 @@ macro_rules! tests { tests! { fn aes, fn arc4, + fn aria, fn base64, fn camellia, fn ccm,