Skip to content

Commit

Permalink
WIP: Add new crypto backend based on mbedtls
Browse files Browse the repository at this point in the history
  • Loading branch information
malishav committed Oct 6, 2023
1 parent 567669d commit bc14964
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 2 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ members = [
"crypto/edhoc-crypto-hacspec",
"crypto/edhoc-crypto-psa",
"crypto/edhoc-crypto-cryptocell310-sys",
"crypto/edhoc-crypto-mbedtls",
"examples/coap",
"examples/edhoc-rs-no_std",
"examples/edhoc-rs-cc2538",
Expand Down
4 changes: 4 additions & 0 deletions crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ edhoc-crypto-psa = { path = "./edhoc-crypto-psa", default-features = false, opti
# cryptocell for nrf52840
edhoc-crypto-cryptocell310 = { path = "./edhoc-crypto-cryptocell310-sys", optional = true }

# mbedtls
edhoc-crypto-mbedtls = { path = "./edhoc-crypto-mbedtls", optional = true }

[features]
default = [ ]
hacspec = [ "edhoc-crypto-hacspec" ]
cc2538 = [ "edhoc-crypto-cc2538" ]
psa = [ "edhoc-crypto-psa" ]
psa-baremetal = [ "psa", "edhoc-crypto-psa/baremetal" ]
cryptocell310 = [ "edhoc-crypto-cryptocell310" ]
mbedtls = [ "edhoc-crypto-mbedtls" ]
14 changes: 14 additions & 0 deletions crypto/edhoc-crypto-mbedtls/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "edhoc-crypto-mbedtls"
version = "0.1.0"
edition = "2021"
authors = ["Mališa Vučinič <malisa.vucinic@inria.fr>"]
license = "BSD"
description = "EDHOC crypto library mbedTLS backend"

[dependencies]
edhoc-consts = { path = "../../consts" }
#mbedtls = { version = "0.9.3" }
mbedtls = { version = "0.9.3", default-features=false, features = ["no_std_deps"] }


161 changes: 161 additions & 0 deletions crypto/edhoc-crypto-mbedtls/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#![no_std]

use edhoc_consts::*;
use mbedtls::bignum::Mpi;
use mbedtls::cipher::raw::Cipher;
use mbedtls::cipher::raw::CipherId;
use mbedtls::cipher::raw::CipherMode;
use mbedtls::cipher::raw::Operation::*;
use mbedtls::ecp::EcGroup;
use mbedtls::ecp::EcPoint;
use mbedtls::hash::Hmac;
use mbedtls::hash::Md;
use mbedtls::hash::Type::Sha256;
use mbedtls::pk::EcGroupId;

pub fn sha256_digest(message: &BytesMaxBuffer, message_len: usize) -> BytesHashLen {
let mut out: [u8; SHA256_DIGEST_LEN] = [0; SHA256_DIGEST_LEN];
Md::hash(Sha256, &message[..message_len], &mut out).unwrap();
out
}

pub fn hkdf_expand(
prk: &BytesHashLen,
info: &BytesMaxInfoBuffer,
info_len: usize,
length: usize,
) -> BytesMaxBuffer {
let mut output: [u8; MAX_BUFFER_LEN] = [0; MAX_BUFFER_LEN];
// Implementation of HKDF-Expand as per RFC5869

let mut n = 0;

// N = ceil(L/HashLen)
if length % SHA256_DIGEST_LEN == 0 {
n = length / SHA256_DIGEST_LEN;
} else {
n = length / SHA256_DIGEST_LEN + 1;
}

let mut message: [u8; MAX_INFO_LEN + SHA256_DIGEST_LEN + 1] =
[0; MAX_INFO_LEN + SHA256_DIGEST_LEN + 1];
message[..info_len].copy_from_slice(&info[..info_len]);
message[info_len] = 0x01;
let mut t_i = hmac_sha256(&message[..info_len + 1], prk);
output[..SHA256_DIGEST_LEN].copy_from_slice(&t_i);

for i in 2..n {
message[..SHA256_DIGEST_LEN].copy_from_slice(&t_i);
message[SHA256_DIGEST_LEN..SHA256_DIGEST_LEN + info_len].copy_from_slice(&info[..info_len]);
message[SHA256_DIGEST_LEN + info_len] = i as u8;
t_i = hmac_sha256(&message[..SHA256_DIGEST_LEN + info_len + 1], prk);
output[i * SHA256_DIGEST_LEN..(i + 1) * SHA256_DIGEST_LEN].copy_from_slice(&t_i);
}

output[length..].fill(0x00);

output
}
pub fn hkdf_extract(salt: &BytesHashLen, ikm: &BytesP256ElemLen) -> BytesHashLen {
// Implementation of HKDF-Extract as per RFC 5869

// TODO generalize if salt is not provided
let output = hmac_sha256(ikm, salt);

output
}

pub fn aes_ccm_encrypt_tag_8(
key: &BytesCcmKeyLen,
iv: &BytesCcmIvLen,
ad: &BytesEncStructureLen,
plaintext: &BufferPlaintext3,
) -> BufferCiphertext3 {
let mut output_buffer: BufferCiphertext3 = BufferCiphertext3::new();

let mut cipher = Cipher::setup(CipherId::Aes, CipherMode::CCM, 128).unwrap();
cipher.set_key(Encrypt, key).unwrap();
cipher.set_iv(iv).unwrap();
let res = cipher
.encrypt_auth(
ad,
&plaintext.content[..plaintext.len],
&mut output_buffer.content,
8,
)
.unwrap();
output_buffer.len = res;

output_buffer
}

pub fn aes_ccm_decrypt_tag_8(
key: &BytesCcmKeyLen,
iv: &BytesCcmIvLen,
ad: &BytesEncStructureLen,
ciphertext: &BufferCiphertext3,
) -> Result<BufferPlaintext3, EDHOCError> {
let mut error = EDHOCError::UnknownError;
let mut output_buffer: BufferPlaintext3 = BufferPlaintext3::new();

let mut cipher = Cipher::setup(CipherId::Aes, CipherMode::CCM, 128).unwrap();
cipher.set_key(Decrypt, key).unwrap();
cipher.set_iv(iv).unwrap();

let res = cipher.decrypt_auth(
ad,
&ciphertext.content[..ciphertext.len],
&mut output_buffer.content,
8,
);

if res.is_ok() {
error = EDHOCError::Success;
output_buffer.len = res.unwrap();
} else {
error = EDHOCError::MacVerificationFailed;
}

match error {
EDHOCError::Success => Ok(output_buffer),
_ => Err(error),
}
}

pub fn p256_ecdh(
private_key: &BytesP256ElemLen,
public_key: &BytesP256ElemLen,
) -> BytesP256ElemLen {
let mut output_buffer = [0u8; P256_ELEM_LEN];
let mut peer_public_key = [0u8; P256_ELEM_LEN + 1];
peer_public_key[0] = 0x02; // sign does not matter for ECDH operation
peer_public_key[1..P256_ELEM_LEN + 1].copy_from_slice(&public_key[..]);
let mut group = EcGroup::new(EcGroupId::SecP256R1).unwrap();
let pubk = EcPoint::from_binary(&group, &peer_public_key).unwrap();
let privk = Mpi::from_binary(private_key).unwrap();
let secret = pubk.mul(&mut group, &privk).unwrap();
let secret_x = secret.x().unwrap().to_binary().unwrap();
output_buffer.copy_from_slice(&secret_x[..]);

output_buffer
}

// TODO
pub fn get_random_byte() -> u8 {
0x00u8
}

// TODO
pub fn p256_generate_key_pair() -> (BytesP256ElemLen, BytesP256ElemLen) {
let mut private_key: [u8; P256_ELEM_LEN] = [0; P256_ELEM_LEN];
let mut public_key: [u8; P256_ELEM_LEN] = [0; P256_ELEM_LEN];

(private_key, public_key)
}

pub fn hmac_sha256(message: &[u8], key: &[u8; SHA256_DIGEST_LEN]) -> BytesHashLen {
let mut out: [u8; SHA256_DIGEST_LEN] = [0; SHA256_DIGEST_LEN];
let res = Hmac::hmac(Sha256, key, message, &mut out).unwrap();

out
}
3 changes: 3 additions & 0 deletions crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ pub use edhoc_crypto_cc2538::*;
#[cfg(any(feature = "psa", feature = "psa-rust",))]
pub use edhoc_crypto_psa::*;

#[cfg(feature = "mbedtls")]
pub use edhoc_crypto_mbedtls::*;

#[cfg(any(feature = "cryptocell310", feature = "cryptocell310-rust"))]
pub use edhoc_crypto_cryptocell310::*;
1 change: 1 addition & 0 deletions examples/edhoc-rs-no_std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ default = [ "rtt", "crypto-cryptocell310", "ead-none" ]
rtt = [ ]
crypto-psa = [ "edhoc-rs/crypto-psa-baremetal" ]
crypto-cryptocell310 = [ "edhoc-rs/crypto-cryptocell310" ]
crypto-mbedtls = [ "edhoc-rs/crypto-mbedtls" ]
ead-none = [ "edhoc-rs/ead-none" ]
ead-zeroconf = [ "edhoc-rs/ead-zeroconf" ]
15 changes: 13 additions & 2 deletions examples/edhoc-rs-no_std/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,21 @@ fn main() -> ! {
loop {}
}

use core::ffi::{c_char, c_void};
use core::ffi::{c_char, c_ulong, c_void};

#[no_mangle]
pub extern "C" fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char {
pub extern "C" fn strstr(_cs: *const c_char, _ct: *const c_char) -> *mut c_char {
panic!("strstr handler!");
core::ptr::null_mut()
}

#[no_mangle]
pub unsafe extern "C" fn calloc(__count: c_ulong, __size: c_ulong) -> *mut c_void {
panic!("calloc handler!");
core::ptr::null_mut()
}

#[no_mangle]
pub unsafe extern "C" fn free(_ptr: *const c_void) {
panic!("free handler!");
}
1 change: 1 addition & 0 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ cbindgen = "0.24.5"
default = [ "edhoc-ead/ead-none" ]
crypto-hacspec = ["hacspec-lib/std", "edhoc-crypto/hacspec" ]
crypto-psa = [ "edhoc-crypto/psa" ]
crypto-mbedtls = [ "edhoc-crypto/mbedtls" ]
crypto-psa-baremetal = [ "edhoc-crypto/psa-baremetal", "panic-semihosting" ]
crypto-cryptocell310 = [ "edhoc-crypto/cryptocell310", "panic-semihosting" ]
ead-none = [ "edhoc-ead/ead-none" ]
Expand Down

0 comments on commit bc14964

Please sign in to comment.