enquo_core/
field.rs

1//! Build It and They Will Come
2//!
3
4use crate::{key_provider::Static, Error, KeyProvider, Root};
5
6/// The type of the ID for a field key
7///
8/// The size of the ID space has been chosen to be large enough to make it practically impossible
9/// for a collision to ever occur in real-world use.
10///
11pub(crate) type KeyId = [u8; 8];
12
13/// The source of all encryption shenanigans.
14///
15/// Gets passed around like a doobie whenever we want to encrypt a data value.
16///
17#[derive(Debug)]
18pub struct Field {
19    /// The key from which all the component keys of the field's encryption are derived
20    ///
21    field_key: Static,
22}
23
24impl Field {
25    /// Create a new Field
26    ///
27    /// Use `Root.field()` instead.
28    ///
29    /// # Errors
30    ///
31    /// Can return an error if the root can't derive the field key.
32    ///
33    pub(crate) fn new(root: &Root, collection: &[u8], name: &[u8]) -> Result<Field, Error> {
34        Ok(Field {
35            field_key: Self::field_key_provider(root, collection, name)?,
36        })
37    }
38
39    /// Derive a specific subkey for some element of this field's cryptographic data.
40    ///
41    /// # Errors
42    ///
43    /// Can return an error if the key provider can't successfully derive the subkey, say because
44    /// of a cryptographic error.
45    ///
46    pub(crate) fn subkey(&self, subkey: &mut [u8], identifier: &[u8]) -> Result<(), Error> {
47        self.field_key.derive_key(subkey, identifier)
48    }
49
50    /// The ID of the key currently being used by this field
51    ///
52    /// Not part of the key itself, obviously, but a way to determine with a reasonable degree of
53    /// confidence if the key used to encrypt a given data value is the same as the key in use on
54    /// this field.
55    ///
56    /// # Errors
57    ///
58    /// Can return an error if the cryptographic operation involved in calculating the key ID fails
59    /// for some reason.
60    ///
61    pub fn key_id(&self) -> Result<KeyId, Error> {
62        let mut id: KeyId = Default::default();
63        self.field_key.derive_key(&mut id, b"Field.key_id")?;
64        Ok(id)
65    }
66
67    /// Create the provider for the key for this field
68    ///
69    /// As key providers do all the hard work of actually deriving new keys from a "base" key, a
70    /// field needs a key provider to do that, which -- as field keys are local, can just be our
71    /// bog-basic `Static` provider.
72    ///
73    /// # Errors
74    ///
75    /// Can crap out if the root can't derive the field key.
76    ///
77    fn field_key_provider(root: &Root, collection: &[u8], name: &[u8]) -> Result<Static, Error> {
78        // Saturating math is fine because it's only a capacity calculation
79        let mut id = Vec::<u8>::with_capacity(
80            collection
81                .len()
82                .saturating_add(name.len())
83                .saturating_add(1),
84        );
85
86        id.extend(collection);
87        id.push(0);
88        id.extend(name);
89
90        let mut field_key: [u8; 32] = Default::default();
91        root.derive_key(&mut field_key, &id)?;
92
93        Static::new(&field_key)
94    }
95}
96
97#[cfg(test)]
98mod tests {
99    use super::*;
100    use crate::key_provider::Static;
101    use hex_literal::hex;
102    use std::sync::Arc;
103
104    #[test]
105    fn has_a_key_id() {
106        let rk = Arc::new(Static::new(b"this is a suuuuper long test key").unwrap());
107        let f = Root::new(rk)
108            .unwrap()
109            .field(b"users", b"full_name")
110            .unwrap();
111
112        assert_eq!(hex!["494d15e1 4ab748dd"], f.key_id().unwrap());
113    }
114
115    #[test]
116    fn different_fields_have_different_key_ids() {
117        let rk = Arc::new(Static::new(b"this is a suuuuper long test key").unwrap());
118        let root = Root::new(rk).unwrap();
119        let f1 = root.field(b"users", b"full_name").unwrap();
120        let f2 = root.field(b"users", b"date_of_birth").unwrap();
121
122        assert_ne!(f1.key_id().unwrap(), f2.key_id().unwrap());
123    }
124
125    #[test]
126    fn generates_subkey() {
127        let rk = Arc::new(Static::new(b"this is a suuuuper long test key").unwrap());
128        let f = Root::new(rk)
129            .unwrap()
130            .field(b"users", b"full_name")
131            .unwrap();
132
133        let mut smol_sk: [u8; 4] = Default::default();
134        f.subkey(&mut smol_sk, b"bob").unwrap();
135
136        assert_eq!(hex!["f2c1753f"], smol_sk);
137
138        let mut sk: [u8; 16] = Default::default();
139        f.subkey(&mut sk, b"bob").unwrap();
140
141        assert_eq!(hex!["f2c1753f 31c6cffe 6c387563 84ada729"], sk);
142
143        let mut sk: [u8; 32] = Default::default();
144        f.subkey(&mut sk, b"bob").unwrap();
145
146        assert_eq!(
147            hex!["f2c1753f 31c6cffe 6c387563 84ada729 480d6f9f 9dd228ae 5ccd833b b8eee70f"],
148            sk
149        );
150    }
151}