ring/aead/
less_safe_key.rs1use super::{Aad, Algorithm, KeyInner, Nonce, Tag, UnboundKey, TAG_LEN};
16use crate::{cpu, error};
17use core::ops::RangeFrom;
18
19#[derive(Clone)]
24pub struct LessSafeKey {
25 inner: KeyInner,
26 algorithm: &'static Algorithm,
27}
28
29impl LessSafeKey {
30 #[inline]
32 pub fn new(key: UnboundKey) -> Self {
33 key.into_inner()
34 }
35
36 pub(super) fn new_(
37 algorithm: &'static Algorithm,
38 key_bytes: &[u8],
39 cpu_features: cpu::Features,
40 ) -> Result<Self, error::Unspecified> {
41 Ok(Self {
42 inner: algorithm.new_key(key_bytes, cpu_features)?,
43 algorithm,
44 })
45 }
46
47 #[inline]
50 pub fn open_in_place_separate_tag<'in_out, A>(
51 &self,
52 nonce: Nonce,
53 aad: Aad<A>,
54 tag: Tag,
55 in_out: &'in_out mut [u8],
56 ciphertext: RangeFrom<usize>,
57 ) -> Result<&'in_out mut [u8], error::Unspecified>
58 where
59 A: AsRef<[u8]>,
60 {
61 let aad = Aad::from(aad.as_ref());
62 self.algorithm.open_within(
63 &self.inner,
64 nonce,
65 aad,
66 tag,
67 in_out,
68 ciphertext,
69 cpu::features(),
70 )
71 }
72
73 #[inline]
78 pub fn open_in_place<'in_out, A>(
79 &self,
80 nonce: Nonce,
81 aad: Aad<A>,
82 in_out: &'in_out mut [u8],
83 ) -> Result<&'in_out mut [u8], error::Unspecified>
84 where
85 A: AsRef<[u8]>,
86 {
87 self.open_within(nonce, aad, in_out, 0..)
88 }
89
90 #[inline]
95 pub fn open_within<'in_out, A>(
96 &self,
97 nonce: Nonce,
98 aad: Aad<A>,
99 in_out: &'in_out mut [u8],
100 ciphertext_and_tag: RangeFrom<usize>,
101 ) -> Result<&'in_out mut [u8], error::Unspecified>
102 where
103 A: AsRef<[u8]>,
104 {
105 let tag_offset = in_out
106 .len()
107 .checked_sub(TAG_LEN)
108 .ok_or(error::Unspecified)?;
109
110 let (in_out, received_tag) = in_out.split_at_mut(tag_offset);
112 let received_tag = (*received_tag).try_into()?;
113 let ciphertext = ciphertext_and_tag;
114
115 self.open_in_place_separate_tag(nonce, aad, received_tag, in_out, ciphertext)
116 }
117
118 #[inline]
123 pub fn seal_in_place_append_tag<A, InOut>(
124 &self,
125 nonce: Nonce,
126 aad: Aad<A>,
127 in_out: &mut InOut,
128 ) -> Result<(), error::Unspecified>
129 where
130 A: AsRef<[u8]>,
131 InOut: AsMut<[u8]> + for<'in_out> Extend<&'in_out u8>,
132 {
133 self.seal_in_place_separate_tag(nonce, aad, in_out.as_mut())
134 .map(|tag| in_out.extend(tag.as_ref()))
135 }
136
137 #[inline]
142 pub fn seal_in_place_separate_tag<A>(
143 &self,
144 nonce: Nonce,
145 aad: Aad<A>,
146 in_out: &mut [u8],
147 ) -> Result<Tag, error::Unspecified>
148 where
149 A: AsRef<[u8]>,
150 {
151 self.algorithm.seal(
152 &self.inner,
153 nonce,
154 Aad::from(aad.as_ref()),
155 in_out,
156 cpu::features(),
157 )
158 }
159
160 #[inline]
162 pub fn algorithm(&self) -> &'static Algorithm {
163 self.algorithm
164 }
165
166 pub(super) fn fmt_debug(
167 &self,
168 type_name: &'static str,
169 f: &mut core::fmt::Formatter,
170 ) -> Result<(), core::fmt::Error> {
171 f.debug_struct(type_name)
172 .field("algorithm", &self.algorithm())
173 .finish()
174 }
175}
176
177impl core::fmt::Debug for LessSafeKey {
178 fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
179 self.fmt_debug("LessSafeKey", f)
180 }
181}