diff --git a/Cargo.toml b/Cargo.toml
index 5109187..caeae02 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -25,6 +25,16 @@
 # We pin the serde version because newer serde versions may not be compatible
 # with the nightly toolchain used by libtock-rs.
 serde = { version = "=1.0.114", default-features = false, features = ["derive"] }
+ctap2-authenticator = { git = "https://gitlab.com/ctap2-authenticator/ctap2-authenticator.git" }
+p256 = { version = "0.5.0" , default-features = false, features = ["arithmetic", "ecdsa", "ecdsa-core"] }
+subtle = { version = "2.3.0", default-features = false, features = ["i128"] }
+generic-array = { version = "0.14.3" }
+
+# We need to override this to allow builds for targets that don't support atomics.
+# Once a version newer then 0.4.11 is released we can update to use that.
+# See: https://github.com/rust-lang/log/releases
+[patch.crates-io]
+log = { git = "https://github.com/rust-lang/log.git", branch = "master" }
 
 [[example]]
 name = "alloc_error"
@@ -32,6 +42,11 @@
 required-features = ["alloc", "custom_alloc_error_handler"]
 
 [[example]]
+name = "ctap_features"
+path = "examples-features/ctap.rs"
+required-features = ["alloc", "custom_alloc_error_handler"]
+
+[[example]]
 name = "ble_scanning"
 path = "examples-features/ble_scanning.rs"
 required-features = ["alloc"]
diff --git a/examples-features/ctap.rs b/examples-features/ctap.rs
new file mode 100644
index 0000000..3a66eff
--- /dev/null
+++ b/examples-features/ctap.rs
@@ -0,0 +1,507 @@
+//! This is a featured CTAP example
+//! WARNING! This currently uses unsound crypto operations
+//! This is only a demo and should not be used in real enviroments
+#![no_std]
+#![feature(alloc_error_handler)]
+
+extern crate alloc;
+
+use core::alloc::Layout;
+use core::cell::Cell;
+use core::convert::TryInto;
+use core::fmt::{self, Debug, Error, Formatter};
+use core::time::Duration;
+use ctap2_authenticator::credentials::{RpCredential, UserCredential};
+use ctap2_authenticator::usbhid::{
+    CtapHidCapabilities, CtapHidPlatform, KeepaliveResponse, TransactionProcessor,
+};
+use ctap2_authenticator::Authenticator;
+use ctap2_authenticator::{
+    AuthenticatorPlatform, CredentialDescriptorList, CtapOptions, PublicKey, Signature,
+};
+use generic_array::GenericArray;
+use libtock::ctap::{CtapRecvBuffer, CtapSendBuffer};
+use libtock::hmac::{HmacDataBuffer, HmacDestBuffer, HmacDriverFactory, HmacKeyBuffer};
+use libtock::println;
+use libtock::result::TockResult;
+use libtock::syscalls;
+use p256::ecdsa::{signature::Signer, SigningKey};
+use p256::elliptic_curve::ff::PrimeField;
+use p256::{Scalar, SecretKey};
+use subtle::{Choice, ConditionallySelectable};
+
+#[derive(Debug, Clone, PartialEq, Eq, Copy)]
+pub struct PrivateKey(Scalar);
+
+impl ConditionallySelectable for PrivateKey {
+    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
+        Self(ConditionallySelectable::conditional_select(
+            &a.0, &b.0, choice,
+        ))
+    }
+}
+
+impl Default for PrivateKey {
+    fn default() -> Self {
+        Self(Scalar::default())
+    }
+}
+
+impl PrivateKey {
+    pub fn from_bytes(bytes: &[u8; 32]) -> Option<Self> {
+        Scalar::from_repr(GenericArray::clone_from_slice(bytes)).map(|s| Self(s))
+    }
+}
+
+/// This is the provided implementation of `CtapHidPlatform` to be used in the `UsbContext`
+pub(crate) struct UsbKeyHidPlatform {}
+
+impl UsbKeyHidPlatform {
+    pub fn new() -> Self {
+        Self {}
+    }
+}
+
+impl CtapHidPlatform for UsbKeyHidPlatform {
+    // Should be kept in sync with the Crates version if possible
+    const MAJOR_VERSION: u8 = 0;
+    const MINOR_VERSION: u8 = 0;
+    const BUILD_VERSION: u8 = 0;
+    const CAPABILITIES: CtapHidCapabilities = CtapHidCapabilities {
+        wink: true,
+        cbor: true,
+        msg: false,
+    };
+
+    fn wink(&mut self) {}
+
+    fn cancel(&mut self) {
+        println!("cancel");
+        unimplemented!()
+    }
+
+    fn keepalive_needed(&mut self) -> KeepaliveResponse {
+        println!("keepalive_needed");
+        unimplemented!()
+    }
+
+    fn start_timer(&mut self) {
+        println!("start_timer");
+    }
+
+    fn has_timed_out(&mut self) -> bool {
+        println!("has_timed_out");
+        false
+    }
+}
+
+#[derive(Clone, Copy)]
+pub struct HmacKeyCredential(pub(crate) [u8; 40]);
+
+impl HmacKeyCredential {
+    fn new(mac: &[u8; 32], nonce: [u8; 8]) -> Self {
+        let mut new = [0; 40];
+        new[..32].copy_from_slice(&mac[..]);
+        new[32..].copy_from_slice(&nonce[..]);
+        Self(new)
+    }
+
+    fn get_mac(&self) -> [u8; 32] {
+        let mut mac = [0; 32];
+        mac.copy_from_slice(&self.0[..32]);
+        mac
+    }
+}
+
+impl AsRef<[u8]> for HmacKeyCredential {
+    fn as_ref(&self) -> &[u8] {
+        &self.0
+    }
+}
+
+impl Debug for HmacKeyCredential {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+        write!(
+            f,
+            "HmacKeyCredential {{ mac: {:?}, nonce: {:?} }}",
+            &self.0[..32],
+            &self.0[32..]
+        )
+    }
+}
+
+impl PartialEq for HmacKeyCredential {
+    fn eq(&self, other: &Self) -> bool {
+        self.0[..] == other.0[..]
+    }
+}
+
+impl Eq for HmacKeyCredential {}
+
+const ITERATOR_MAX_LENGTH: usize = 8;
+
+pub struct HmacCredentialQueue {
+    index: usize,
+    length: usize,
+    list: [Option<(HmacKeyCredential, u32)>; ITERATOR_MAX_LENGTH],
+}
+
+impl HmacCredentialQueue {
+    pub(crate) fn new() -> Self {
+        Self {
+            index: 0,
+            length: 0,
+            list: [None; ITERATOR_MAX_LENGTH],
+        }
+    }
+
+    pub(crate) fn push(&mut self, credential: HmacKeyCredential, counter: u32) -> Result<(), ()> {
+        if self.length < ITERATOR_MAX_LENGTH {
+            self.list[self.length] = Some((credential, counter));
+            self.length += 1;
+            Ok(())
+        } else {
+            Err(())
+        }
+    }
+
+    pub(crate) fn len(&self) -> usize {
+        self.length
+    }
+}
+
+impl Iterator for HmacCredentialQueue {
+    type Item = (HmacKeyCredential, u32);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.list[self.index].is_some() {
+            self.index += 1;
+            self.list[self.index - 1]
+        } else {
+            None
+        }
+    }
+}
+
+pub(crate) struct CtapPlatform {
+    hmac: HmacDriverFactory,
+}
+
+impl CtapPlatform {
+    fn new(hmac: HmacDriverFactory) -> Self {
+        Self { hmac }
+    }
+}
+
+impl fmt::Debug for CtapPlatform {
+    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        Ok(())
+    }
+}
+
+impl CtapPlatform {
+    fn generate_key_seed(
+        &mut self,
+        rp_id: &str,
+        nonce: &[u8; 8],
+    ) -> [u8; libtock::hmac::DEST_BUFFER_SIZE] {
+        let hmac_driver;
+        match self.hmac.init_driver() {
+            Err(_) => {
+                panic!("Hmac init error");
+            }
+            Ok(driver) => {
+                hmac_driver = driver;
+            }
+        }
+
+        let mut key_buffer = HmacKeyBuffer::default();
+        for (i, d) in rp_id.as_bytes().iter().enumerate() {
+            key_buffer[i] = *d;
+        }
+        // We need to make sure this isn't dropped straight away
+        let key_buffer_ret = hmac_driver.init_key_buffer(&mut key_buffer);
+        if key_buffer_ret.is_err() {
+            panic!("Hmac key buffer init error");
+        }
+
+        let mut data_buffer = HmacDataBuffer::default();
+        for (i, d) in nonce.iter().enumerate() {
+            data_buffer[i] = *d;
+        }
+        // We need to make sure this isn't dropped straight away
+        let data_buffer_ret = hmac_driver.init_data_buffer(&mut data_buffer);
+        if data_buffer_ret.is_err() {
+            panic!("Hmac data buffer init error");
+        }
+
+        let mut dest_buffer = HmacDestBuffer::default();
+        let seed_buffer;
+        match hmac_driver.init_dest_buffer(&mut dest_buffer) {
+            Err(_) => {
+                panic!("Hmac subscribe error");
+            }
+            Ok(buffer) => {
+                seed_buffer = buffer;
+            }
+        }
+
+        let mut callback = |_result, _digest| {};
+
+        // We need to make sure this isn't dropped straight away
+        let subscribe = hmac_driver.subscribe(&mut callback);
+        if subscribe.is_err() {
+            panic!("Hmac subscribe error");
+        }
+
+        if hmac_driver.run().is_err() {
+            panic!("Hmac run error");
+        }
+
+        // Yield waiting for the HMAC callback
+        unsafe {
+            syscalls::raw::yieldk();
+        }
+
+        let mut temp_buffer = [0; libtock::hmac::DEST_BUFFER_SIZE];
+        seed_buffer.read_bytes(&mut temp_buffer[..]);
+        temp_buffer
+    }
+
+    /// Generates a Credential from a CredentialId and checks that the Id is valid
+    fn checked_generate_hmac_cred(
+        &mut self,
+        rp_id: &str,
+        credential_id: &[u8],
+    ) -> Option<HmacKeyCredential> {
+        if credential_id.len() != 40 {
+            return None;
+        }
+
+        let received_mac = &credential_id[..32];
+
+        let seed_buffer = self.generate_key_seed(rp_id, &credential_id[32..40].try_into().unwrap());
+
+        let credential =
+            HmacKeyCredential::new(&seed_buffer, credential_id[32..].try_into().unwrap());
+
+        let generated_mac = &credential.0[..32];
+
+        if generated_mac == received_mac {
+            Some(credential)
+        } else {
+            None
+        }
+    }
+}
+
+impl AuthenticatorPlatform for CtapPlatform {
+    const AAGUID: [u8; 16] = [
+        0xf8, 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc,
+        0x7d,
+    ];
+    const CERTIFICATE: Option<&'static [u8]> = None;
+    const MAX_MSG_LENGTH: u16 = 7609;
+    const SUPPORTED_OPTIONS: CtapOptions = CtapOptions {
+        plat: None,
+        rk: Some(true),
+        client_pin: None,
+        up: Some(true),
+        uv: Some(false),
+    };
+    type CredentialId = HmacKeyCredential;
+    type PublicKeyBuffer = [u8; 32];
+    type SignatureBuffer = [u8; 32];
+    type CredentialIterator = HmacCredentialQueue;
+
+    fn reset(&mut self) -> Result<(), ()> {
+        println!("reset");
+        unimplemented!()
+    }
+
+    fn check_exclude_list(&mut self, _rp_id: &str, _list: CredentialDescriptorList) -> bool {
+        println!("check_exclude_list");
+        unimplemented!()
+    }
+
+    fn locate_credentials(
+        &mut self,
+        rp_id: &str,
+        list: Option<CredentialDescriptorList>,
+    ) -> (u16, Self::CredentialIterator) {
+        match list {
+            None => (0, HmacCredentialQueue::new()),
+            Some(list) => {
+                let mut result = HmacCredentialQueue::new();
+
+                for descriptor in list {
+                    match self.checked_generate_hmac_cred(rp_id, descriptor.get_id()) {
+                        None => (),
+                        Some(credential) => {
+                            match result.push(credential, 0) {
+                                Ok(()) => (),
+                                // NOTE: We just truncate if we don't have enough space to store all
+                                // fitting credentials
+                                Err(()) => break,
+                            }
+                        }
+                    }
+                }
+
+                (result.len() as u16, result)
+            }
+        }
+    }
+
+    fn create_credential(
+        &mut self,
+        rp: RpCredential<&[u8], &str>,
+        _user: UserCredential<&[u8], &str>,
+    ) -> (Self::CredentialId, PublicKey<Self::PublicKeyBuffer>, u32) {
+        println!("create_credential");
+        let rp_id = core::str::from_utf8(rp.rp_id()).unwrap();
+        // This nonce is static!!!!
+        // This is really bad cryptowise, let's print a warning
+        // TODO: Convert this to generate a nonce from Tock's TRNG
+        println!("WARNING!!! The nonce is static, this key is insecure");
+        println!("WARNING!!! Do not use this anywhere important");
+        let nonce = [0; 8];
+
+        let seed_buffer = self.generate_key_seed(rp_id, &nonce);
+
+        let credential = HmacKeyCredential::new(&seed_buffer, nonce.try_into().unwrap());
+
+        let secret_key = SecretKey::from_bytes(&seed_buffer[0..32]).unwrap();
+
+        let pub_key = p256::EncodedPoint::from_secret_key(&secret_key, false);
+
+        let x: [u8; 32] = pub_key.as_bytes()[1..33].try_into().unwrap();
+        let y: [u8; 32] = pub_key.as_bytes()[33..].try_into().unwrap();
+
+        let ret_key = PublicKey::nistp256(x, y);
+
+        (credential, ret_key, 0)
+    }
+
+    fn attest(
+        &mut self,
+        id: &Self::CredentialId,
+        data: &[u8],
+    ) -> Option<Signature<Self::SignatureBuffer>> {
+        // TODO: Should attest be different then sign?
+        let attest = {
+            let secret_key = SecretKey::from_bytes(id.get_mac()).unwrap();
+
+            let signer = SigningKey::from(&secret_key);
+
+            let sig = signer.sign(data);
+
+            let mut r: [u8; 32] = [0; 32];
+            r.clone_from_slice(&sig.r().as_ref().to_bytes());
+            let mut s: [u8; 32] = [0; 32];
+            s.clone_from_slice(&sig.s().as_ref().to_bytes());
+
+            Signature::nistp256(r, s)
+        };
+
+        Some(attest)
+    }
+
+    fn sign(
+        &mut self,
+        id: &Self::CredentialId,
+        data: &[u8],
+    ) -> Option<Signature<Self::SignatureBuffer>> {
+        let attest = {
+            let secret_key = SecretKey::from_bytes(id.get_mac()).unwrap();
+            let signer = SigningKey::from(&secret_key);
+            let sig = signer.sign(data);
+
+            let mut r: [u8; 32] = [0; 32];
+            r.clone_from_slice(&sig.r().as_ref().to_bytes());
+            let mut s: [u8; 32] = [0; 32];
+            s.clone_from_slice(&sig.s().as_ref().to_bytes());
+
+            Signature::nistp256(r, s)
+        };
+
+        Some(attest)
+    }
+
+    fn start_timeout(&mut self) {
+        println!("start_timeout");
+        unimplemented!()
+    }
+
+    fn has_timed_out(&mut self, _time: Duration) -> bool {
+        println!("has_timed_out");
+        unimplemented!()
+    }
+}
+
+#[alloc_error_handler]
+unsafe fn alloc_error_handler(_: Layout) -> ! {
+    println!("alloc_error_handler called");
+    loop {
+        syscalls::raw::yieldk();
+    }
+}
+
+#[libtock::main]
+async fn main() -> TockResult<()> {
+    let mut tp: Cell<TransactionProcessor<&'static mut [u8], UsbKeyHidPlatform>>;
+    let mut temp_buffer = [0; libtock::ctap::RECV_BUFFER_SIZE];
+    let mut drivers = libtock::retrieve_drivers()?;
+    drivers.console.create_console();
+
+    println!("Starting CTAP feature example");
+
+    let ctap_driver = drivers.ctap.init_driver()?;
+
+    let mut recv_buffer = CtapRecvBuffer::default();
+    let recv_buffer = ctap_driver.init_recv_buffer(&mut recv_buffer)?;
+
+    let mut send_buffer = CtapSendBuffer::default();
+    let mut send_buffer = ctap_driver.init_send_buffer(&mut send_buffer)?;
+
+    static mut BUFFER: &'static mut [u8] = &mut [0; 2048];
+    unsafe {
+        tp = Cell::new(TransactionProcessor::new(BUFFER, UsbKeyHidPlatform::new()));
+    }
+
+    let mut authenticator = Authenticator::create(CtapPlatform::new(drivers.hmac));
+
+    let mut callback = |sent, _| {
+        let mut looping = true;
+        recv_buffer.read_bytes(&mut temp_buffer[..]);
+
+        let temp_tp = tp.get_mut();
+        let mut poll_msg = if sent == 0 { Some(&temp_buffer) } else { None };
+
+        while looping {
+            looping = false;
+            let (maybe_request, maybe_data) = temp_tp.poll(poll_msg);
+
+            if let Some(request) = maybe_request {
+                let response = authenticator.process(request);
+                temp_tp.response(response);
+                looping = true;
+            }
+
+            if let Some(mut data) = maybe_data {
+                send_buffer.write_bytes(&mut data[0..]);
+                let _ = ctap_driver.send_data();
+            }
+
+            poll_msg = None;
+        }
+        let _ = ctap_driver.allow_receive();
+    };
+
+    let _subscription = ctap_driver.subscribe(&mut callback)?;
+    ctap_driver.allow_receive()?;
+
+    loop {
+        unsafe { syscalls::raw::yieldk() };
+    }
+}
