use bitfield::bitfield;
use bytes::Buf;
use serde_derive::Serialize;
bitfield! {
pub struct ReadKey(u8);
impl Debug;
pub external_signatures, set_external_signatures: 0;
pub internal_signatures, set_internal_signatures: 1;
pub ecdh_operation, set_ecdh_operation: 2;
pub ecdh_write_slot, set_ecdh_write_slot: 3;
}
impl From<u8> for ReadKey {
fn from(v: u8) -> Self {
Self(v)
}
}
impl From<ReadKey> for u8 {
fn from(v: ReadKey) -> Self {
v.0
}
}
impl Default for ReadKey {
fn default() -> Self {
let mut result = Self(0);
result.set_internal_signatures(true);
result.set_external_signatures(true);
result.set_ecdh_operation(true);
result
}
}
#[derive(Serialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum WriteConfig {
Write(_WriteConfig),
DeriveKey(DeriveKeyConfig),
GenKey(GenKeyConfig),
PrivWrite(PrivWriteConfig),
}
#[derive(Debug, PartialEq, Eq)]
pub enum WriteCommand {
Write,
DeriveKey,
GenKey,
PrivWrite,
}
impl WriteConfig {
pub fn from(cmd: WriteCommand, v: u8) -> Self {
match cmd {
WriteCommand::Write => Self::Write(v.into()),
WriteCommand::DeriveKey => Self::DeriveKey(v.into()),
WriteCommand::GenKey => Self::GenKey(v.into()),
WriteCommand::PrivWrite => Self::PrivWrite(v.into()),
}
}
}
impl From<WriteConfig> for u8 {
fn from(v: WriteConfig) -> Self {
match v {
WriteConfig::Write(cfg) => cfg.into(),
WriteConfig::DeriveKey(cfg) => cfg.into(),
WriteConfig::GenKey(cfg) => cfg.into(),
WriteConfig::PrivWrite(cfg) => cfg.into(),
}
}
}
impl Default for WriteConfig {
fn default() -> Self {
WriteConfig::GenKey(GenKeyConfig::Valid)
}
}
#[derive(Serialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum _WriteConfig {
Always,
PubInValid,
Never,
Encrypt,
}
impl From<u8> for _WriteConfig {
fn from(v: u8) -> Self {
match v {
0 => _WriteConfig::Always,
1 => _WriteConfig::PubInValid,
_ if v >> 1 == 1 => _WriteConfig::Never,
_ if v >> 2 == 2 => _WriteConfig::Never,
_ if v & 4 == 4 => _WriteConfig::Encrypt,
_ => panic!("invalid write config {:?}", v),
}
}
}
impl From<_WriteConfig> for u8 {
fn from(v: _WriteConfig) -> Self {
match v {
_WriteConfig::Always => 0,
_WriteConfig::PubInValid => 1,
_WriteConfig::Never => 2,
_WriteConfig::Encrypt => 4,
}
}
}
#[derive(Serialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum DeriveKeyConfig {
Roll(bool),
Create(bool),
Invalid,
}
impl From<u8> for DeriveKeyConfig {
fn from(v: u8) -> Self {
match v & 11 {
2 => Self::Roll(false),
10 => Self::Roll(true),
3 => Self::Create(false),
11 => Self::Create(true),
_ => Self::Invalid,
}
}
}
impl From<DeriveKeyConfig> for u8 {
fn from(v: DeriveKeyConfig) -> Self {
match v {
DeriveKeyConfig::Roll(false) => 2,
DeriveKeyConfig::Roll(true) => 10,
DeriveKeyConfig::Create(false) => 3,
DeriveKeyConfig::Create(true) => 11,
DeriveKeyConfig::Invalid => 0,
}
}
}
#[derive(Serialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum GenKeyConfig {
Valid,
Invalid,
}
impl From<u8> for GenKeyConfig {
fn from(v: u8) -> Self {
match v & 2 == 0 {
true => Self::Invalid,
_ => Self::Valid,
}
}
}
impl From<GenKeyConfig> for u8 {
fn from(v: GenKeyConfig) -> Self {
match v {
GenKeyConfig::Invalid => 0,
GenKeyConfig::Valid => 2,
}
}
}
#[derive(Serialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum PrivWriteConfig {
Invalid,
Encrypt,
}
impl From<u8> for PrivWriteConfig {
fn from(v: u8) -> Self {
match v & 4 == 0 {
true => Self::Invalid,
_ => Self::Encrypt,
}
}
}
impl From<PrivWriteConfig> for u8 {
fn from(v: PrivWriteConfig) -> Self {
match v {
PrivWriteConfig::Invalid => 0,
PrivWriteConfig::Encrypt => 4,
}
}
}
bitfield! {
#[derive(PartialEq, Eq)]
pub struct SlotConfig(u16);
impl Debug;
pub secret, set_secret: 15;
pub encrypt_read, set_encrypt_read: 14;
pub limited_use, set_limited_use: 13;
pub no_mac, set_no_mac: 12;
pub u8, from into ReadKey, read_key, set_read_key: 11, 8;
u8, _write_config, _set_write_config: 7, 4;
pub u8, write_key, set_write_key: 3, 0;
}
impl From<&[u8]> for SlotConfig {
fn from(v: &[u8]) -> Self {
let mut buf = v;
Self(buf.get_u16())
}
}
impl From<u16> for SlotConfig {
fn from(v: u16) -> Self {
Self(v)
}
}
impl From<SlotConfig> for u16 {
fn from(v: SlotConfig) -> Self {
v.0
}
}
impl From<&SlotConfig> for u16 {
fn from(v: &SlotConfig) -> Self {
v.0
}
}
impl Default for SlotConfig {
fn default() -> Self {
let mut result = SlotConfig(0);
result.set_write_config(WriteConfig::default());
result.set_write_key(0);
result.set_secret(true);
result.set_encrypt_read(false);
result.set_limited_use(false);
result.set_no_mac(true);
result.set_read_key(ReadKey::default());
result
}
}
impl SlotConfig {
pub fn write_config(&self, cmd: WriteCommand) -> WriteConfig {
WriteConfig::from(cmd, self._write_config())
}
pub fn set_write_config<C>(&mut self, config: C)
where
C: Into<u8>,
{
self._set_write_config(config.into())
}
}
impl serde::ser::Serialize for SlotConfig {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
use serde::ser::SerializeStruct;
let mut state = serializer.serialize_struct("slot_config", 7)?;
state.serialize_field("secret", &self.secret())?;
state.serialize_field("encrypt_read", &self.encrypt_read())?;
state.serialize_field("limited_use", &self.limited_use())?;
state.serialize_field("no_mac", &self.no_mac())?;
state.serialize_field("read_key", &self.read_key())?;
state.serialize_field("write_config", &self._write_config())?;
state.serialize_field("write_key", &self.write_key())?;
state.end()
}
}
impl serde::ser::Serialize for ReadKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
use serde::ser::SerializeStruct;
let mut state = serializer.serialize_struct("read_key", 7)?;
state.serialize_field("external_signatures", &self.external_signatures())?;
state.serialize_field("internal_signatures", &self.internal_signatures())?;
state.serialize_field("ecdh_operation", &self.ecdh_operation())?;
state.serialize_field("ecdh_write_slot", &self.ecdh_write_slot())?;
state.end()
}
}