Repository: google/OpenSK
File: src/ctap/mod.rs (Rust)

Code before:
    }

    #[test]
    fn test_encrypt_decrypt_bad_hmac() {
        let mut rng = ThreadRng256 {};
        let user_immediately_present = |_| Ok(());
        let private_key = crypto::ecdsa::SecKey::gensk(&mut rng);
        let mut ctap_state = CtapState::new(&mut rng, user_immediately_present);

        // Same as above.
        let rp_id_hash = [0x55; 32];
        let encrypted_id = ctap_state.encrypt_key_handle(private_key, &rp_id_hash);
        for i in 0..encrypted_id.len() {
            let mut modified_id = encrypted_id.clone();
            modified_id[i] ^= 0x01;
            assert!(ctap_state
                .decrypt_credential_source(modified_id, &rp_id_hash)
                .is_none());
        }
    }

    #[test]
    fn test_encrypt_hmac_secret_output() {
        let shared_secret = [0x55; 32];
        let salt_enc = vec![0x5E; 32];
        let cred_random = vec![0xC9; 32];
        let output = encrypt_hmac_secret_output(&shared_secret, salt_enc, &cred_random);
        assert_eq!(output.unwrap().len(), 32);

        let salt_enc = vec![0x5E; 48];
        let output = encrypt_hmac_secret_output(&shared_secret, salt_enc, &cred_random);
        assert_eq!(
            output,
            Err(Ctap2StatusCode::CTAP2_ERR_UNSUPPORTED_EXTENSION)
        );

        let salt_enc = vec![0x5E; 64];
        let output = encrypt_hmac_secret_output(&shared_secret, salt_enc, &cred_random);
        assert_eq!(output.unwrap().len(), 64);

        let salt_enc = vec![0x5E; 32];
        let cred_random = vec![0xC9; 33];
        let output = encrypt_hmac_secret_output(&shared_secret, salt_enc, &cred_random);
        assert_eq!(
            output,
            Err(Ctap2StatusCode::CTAP2_ERR_UNSUPPORTED_EXTENSION)
        );
    }
}


Review comment (security):
This doesn't need to be a Vec. Neither does `salt_enc` if `encrypt_hmac_secret_output` takes a slice.

Code after:

    #[test]
    fn test_encrypt_decrypt_bad_hmac() {
        let mut rng = ThreadRng256 {};
        let user_immediately_present = |_| Ok(());
        let private_key = crypto::ecdsa::SecKey::gensk(&mut rng);
        let mut ctap_state = CtapState::new(&mut rng, user_immediately_present);

        // Same as above.
        let rp_id_hash = [0x55; 32];
        let encrypted_id = ctap_state.encrypt_key_handle(private_key, &rp_id_hash);
        for i in 0..encrypted_id.len() {
            let mut modified_id = encrypted_id.clone();
            modified_id[i] ^= 0x01;
            assert!(ctap_state
                .decrypt_credential_source(modified_id, &rp_id_hash)
                .is_none());
        }
    }

    #[test]
    fn test_encrypt_hmac_secret_output() {
        let shared_secret = [0x55; 32];
        let salt_enc = [0x5E; 32];
        let cred_random = [0xC9; 32];
        let output = encrypt_hmac_secret_output(&shared_secret, &salt_enc, &cred_random);
        assert_eq!(output.unwrap().len(), 32);

        let salt_enc = [0x5E; 48];
        let output = encrypt_hmac_secret_output(&shared_secret, &salt_enc, &cred_random);
        assert_eq!(
            output,
            Err(Ctap2StatusCode::CTAP2_ERR_UNSUPPORTED_EXTENSION)
        );

        let salt_enc = [0x5E; 64];
        let output = encrypt_hmac_secret_output(&shared_secret, &salt_enc, &cred_random);
        assert_eq!(output.unwrap().len(), 64);

        let salt_enc = [0x5E; 32];
        let cred_random = [0xC9; 33];
        let output = encrypt_hmac_secret_output(&shared_secret, &salt_enc, &cred_random);
        assert_eq!(
            output,
            Err(Ctap2StatusCode::CTAP2_ERR_UNSUPPORTED_EXTENSION)
        );
    }
}