lib.rs
1 use std::mem::MaybeUninit; 2 3 #[allow( 4 non_camel_case_types, 5 unsafe_op_in_unsafe_fn, 6 clippy::missing_safety_doc 7 )] 8 pub mod bindings; 9 10 pub type XSalsa20Key = [u8; 32]; 11 pub type XSalsa20Nonce = [u8; 24]; 12 13 pub type Poly1305Key = bindings::poly1305_key; 14 pub type Poly1305Tag = bindings::poly1305_mac; 15 16 #[repr(transparent)] 17 pub struct XSalsa20(bindings::crypton_salsa_context); 18 19 impl XSalsa20 { 20 pub const KEY_LEN: usize = std::mem::size_of::<XSalsa20Key>(); 21 pub const NONCE_LEN: usize = std::mem::size_of::<XSalsa20Nonce>(); 22 23 pub fn init(key: &XSalsa20Key, nonce: &XSalsa20Nonce) -> Self { 24 let mut xsalsa20: MaybeUninit<bindings::crypton_salsa_context> = MaybeUninit::uninit(); 25 26 let xsalsa20 = unsafe { 27 let ctx: *mut bindings::crypton_salsa_context = xsalsa20.as_mut_ptr(); 28 let nb_rounds: u8 = 20; 29 let keylen: u32 = Self::KEY_LEN as u32; 30 let key: *const u8 = key.as_ptr(); 31 let ivlen = Self::NONCE_LEN as u32; 32 let iv: *const u8 = nonce.as_ptr(); 33 34 bindings::crypton_xsalsa_init(ctx, nb_rounds, keylen, key, ivlen, iv); 35 xsalsa20.assume_init() 36 }; 37 38 Self(xsalsa20) 39 } 40 41 pub fn derive(mut self, iv: &[u8; 16]) -> Self { 42 unsafe { 43 let ctx: *mut bindings::crypton_salsa_context = self.as_mut_ptr(); 44 let ivlen: u32 = std::mem::size_of_val(iv) as u32; 45 let iv: *const u8 = iv.as_ptr(); 46 47 bindings::crypton_xsalsa_derive(ctx, ivlen, iv); 48 self 49 } 50 } 51 52 pub fn generate_into(&mut self, output: &mut [u8]) { 53 unsafe { 54 let dst: *mut u8 = output.as_mut_ptr(); 55 let st: *mut bindings::crypton_salsa_context = self.as_mut_ptr(); 56 let bytes = output.len().try_into().unwrap(); 57 58 bindings::crypton_salsa_generate(dst, st, bytes); 59 } 60 } 61 62 pub fn generate(&mut self, bytes: usize) -> Vec<u8> { 63 let mut output = vec![0u8; bytes]; 64 self.generate_into(&mut output); 65 output 66 } 67 68 pub fn combine_into(&mut self, src: &[u8], output: &mut [u8]) { 69 assert!( 70 src.len() <= output.len(), 71 "combine_into: src.len > output.len" 72 ); 73 74 unsafe { 75 let dst: *mut u8 = output.as_mut_ptr(); 76 let st: *mut bindings::crypton_salsa_context = self.as_mut_ptr(); 77 let src: *const u8 = src.as_ptr(); 78 let bytes: u32 = output.len().try_into().unwrap(); 79 80 bindings::crypton_salsa_combine(dst, st, src, bytes); 81 } 82 } 83 84 pub fn combine(&mut self, src: &[u8]) -> Vec<u8> { 85 let mut output = vec![0u8; src.len()]; 86 self.combine_into(src, &mut output); 87 output 88 } 89 90 pub fn as_ptr(&self) -> *const bindings::crypton_salsa_context { 91 // repr: transparent 92 self as *const Self as *const bindings::crypton_salsa_context 93 } 94 95 pub fn as_mut_ptr(&mut self) -> *mut bindings::crypton_salsa_context { 96 // repr: transparent 97 self as *mut Self as *mut bindings::crypton_salsa_context 98 } 99 } 100 101 #[repr(transparent)] 102 pub struct Poly1305(bindings::poly1305_ctx); 103 104 impl Poly1305 { 105 pub const KEY_LEN: usize = std::mem::size_of::<Poly1305Key>(); 106 pub const TAG_LEN: usize = std::mem::size_of::<Poly1305Tag>(); 107 108 pub fn init(key: &mut Poly1305Key) -> Self { 109 let mut poly1305: MaybeUninit<bindings::poly1305_ctx> = MaybeUninit::uninit(); 110 111 let poly1305 = unsafe { 112 let ctx: *mut bindings::poly1305_ctx = poly1305.as_mut_ptr(); 113 let key: *mut bindings::poly1305_key = key as *mut bindings::poly1305_key; 114 115 bindings::crypton_poly1305_init(ctx, key); 116 poly1305.assume_init() 117 }; 118 119 Self(poly1305) 120 } 121 122 pub fn update(&mut self, input: &mut [u8]) { 123 unsafe { 124 let ctx: *mut bindings::poly1305_ctx = self.as_mut_ptr(); 125 let data: *mut u8 = input.as_mut_ptr(); 126 let length: u32 = input.len().try_into().unwrap(); 127 128 bindings::crypton_poly1305_update(ctx, data, length); 129 } 130 } 131 132 pub fn finalize(&mut self) -> Poly1305Tag { 133 let mut tag: Poly1305Tag = [0u8; 16]; 134 135 unsafe { 136 let ctx: *mut bindings::poly1305_ctx = self.as_mut_ptr(); 137 let mac: *mut u8 = tag.as_mut_ptr(); 138 139 bindings::crypton_poly1305_finalize(mac, ctx); 140 } 141 142 tag 143 } 144 145 pub fn as_ptr(&self) -> *const bindings::poly1305_ctx { 146 // repr: transparent 147 self as *const Self as *mut bindings::poly1305_ctx 148 } 149 150 pub fn as_mut_ptr(&mut self) -> *mut bindings::poly1305_ctx { 151 // repr: transparent 152 self as *mut Self as *mut bindings::poly1305_ctx 153 } 154 }