wolfcose 0.1.0

Safe Rust API for wolfSSL wolfCOSE.
#![allow(missing_docs)]

use wolfcose::{
    decrypt0_into, encrypt0_detached_into, encrypt0_into, encrypt0_to_vec, verify0_into, Algorithm,
    CoseKey, CoseKeyBuilder, Encrypt0Builder, Error, PayloadMode,
};

const PAYLOAD: &[u8] = b"secured drone payload";
const AAD: &[u8] = b"drone-protocol/v1:test";
const IV: [u8; 12] = *b"unique-iv-01";

fn aes_key() -> CoseKey {
    CoseKeyBuilder::symmetric([0x11; 16])
        .algorithm(Algorithm::A128GCM)
        .kid(b"aes")
        .build()
        .unwrap()
}

#[test]
fn encrypt0_attached_detached_and_builder_paths_round_trip() {
    let key = aes_key();
    let mut scratch = [0; 1024];
    let mut out = [0; 512];
    let message = encrypt0_into(
        &key,
        Algorithm::A128GCM,
        &IV,
        PAYLOAD,
        AAD,
        &mut scratch,
        &mut out,
    )
    .unwrap()
    .to_vec();
    assert_eq!(
        encrypt0_to_vec(&key, Algorithm::A128GCM, &IV, PAYLOAD, AAD, &mut scratch).unwrap(),
        message
    );

    let mut plaintext = [0; 128];
    let decrypted = decrypt0_into(&key, &message, None, AAD, &mut scratch, &mut plaintext).unwrap();
    assert_eq!(&plaintext[..decrypted.plaintext_len], PAYLOAD);
    let verified = verify0_into(&key, &message, None, AAD, &mut scratch, &mut plaintext).unwrap();
    assert_eq!(verified.plaintext_len, PAYLOAD.len());

    let mut builder_out = [0; 512];
    let mut builder = Encrypt0Builder::new()
        .key(&key)
        .algorithm(Algorithm::A128GCM)
        .iv(&IV)
        .external_aad(AAD)
        .payload(PayloadMode::Attached(PAYLOAD))
        .scratch_len(1024);
    let builder_message = builder.encrypt_into(&mut builder_out).unwrap().to_vec();
    let builder_vec = builder.encrypt_to_vec().unwrap();
    assert_eq!(builder_message, builder_vec);
    let output = builder
        .decrypt_into(&builder_vec, None, &mut plaintext)
        .unwrap();
    assert_eq!(&plaintext[..output.plaintext_len], PAYLOAD);

    let mut detached_msg = [0; 512];
    let mut detached_ct = [0; 256];
    let detached = encrypt0_detached_into(
        &key,
        Algorithm::A128GCM,
        &IV,
        PAYLOAD,
        AAD,
        &mut scratch,
        &mut detached_msg,
        &mut detached_ct,
    )
    .unwrap();
    let output = decrypt0_into(
        &key,
        &detached_msg[..detached.message_len],
        Some(&detached_ct[..detached.ciphertext_len]),
        AAD,
        &mut scratch,
        &mut plaintext,
    )
    .unwrap();
    assert_eq!(&plaintext[..output.plaintext_len], PAYLOAD);
    assert_eq!(
        decrypt0_into(
            &key,
            &detached_msg[..detached.message_len],
            None,
            AAD,
            &mut scratch,
            &mut plaintext
        ),
        Err(Error::DetachedPayload)
    );

    let mut detached_builder = Encrypt0Builder::new()
        .key(&key)
        .algorithm(Algorithm::A128GCM)
        .iv(&IV)
        .external_aad(AAD)
        .payload(PayloadMode::Detached(PAYLOAD));
    let detached = detached_builder
        .encrypt_detached_into(&mut detached_msg, &mut detached_ct)
        .unwrap();
    assert!(detached.message_len > 0);
    assert_eq!(
        Encrypt0Builder::new()
            .key(&key)
            .algorithm(Algorithm::A128GCM)
            .iv(&IV)
            .payload(PayloadMode::Detached(PAYLOAD))
            .encrypt_to_vec(),
        Err(Error::InvalidArgument)
    );
}