opentitanlib/crypto/
ecdsa.rs1use anyhow::{Context, Result, anyhow, ensure};
6use ecdsa::Signature;
7use ecdsa::elliptic_curve::pkcs8::{DecodePrivateKey, EncodePrivateKey};
8use ecdsa::elliptic_curve::pkcs8::{DecodePublicKey, EncodePublicKey};
9use ecdsa::signature::hazmat::PrehashVerifier;
10use p256::NistP256;
11use p256::ecdsa::{SigningKey, VerifyingKey};
12use pem_rfc7468::Decoder;
13use rand::rngs::OsRng;
14use serde::Deserialize;
15use serde_annotate::Annotate;
16use sha2::digest::generic_array::GenericArray;
17use std::fs::File;
18use std::io::{Read, Write};
19use std::path::Path;
20use std::str::FromStr;
21
22use super::Error;
23use crate::crypto::sha256::Sha256Digest;
24use util::clean_pem_bytes_for_parsing;
25
26pub struct EcdsaPrivateKey {
27 pub key: SigningKey,
28}
29
30pub struct EcdsaPublicKey {
31 pub key: VerifyingKey,
32}
33
34impl Default for EcdsaPrivateKey {
35 fn default() -> Self {
36 Self::new()
37 }
38}
39
40impl EcdsaPrivateKey {
41 pub fn new() -> Self {
42 Self {
43 key: SigningKey::random(&mut OsRng),
44 }
45 }
46
47 pub fn save(&self, path: impl AsRef<Path>) -> Result<()> {
48 self.key.write_pkcs8_der_file(path)?;
49 Ok(())
50 }
51
52 pub fn load(path: impl AsRef<Path>) -> Result<Self> {
53 let key = SigningKey::read_pkcs8_der_file(path)?;
54 Ok(Self { key })
55 }
56
57 pub fn public_key(&self) -> EcdsaPublicKey {
58 EcdsaPublicKey {
59 key: *self.key.verifying_key(),
60 }
61 }
62
63 pub fn sign(&self, digest: &Sha256Digest) -> Result<EcdsaRawSignature> {
64 let (sig, _) = self.key.sign_prehash_recoverable(digest.as_ref())?;
65 let bytes = sig.to_bytes();
66 let half = bytes.len() / 2;
67 let mut r = Vec::new();
71 r.extend(bytes[..half].iter().rev());
72 let mut s = Vec::new();
73 s.extend(bytes[half..].iter().rev());
74 Ok(EcdsaRawSignature { r, s })
75 }
76
77 pub fn digest_and_sign(&self, data: &[u8]) -> Result<EcdsaRawSignature> {
78 self.sign(&Sha256Digest::hash(data))
79 }
80}
81
82#[derive(Debug, Clone, Deserialize, Annotate, PartialEq)]
83pub struct EcdsaRawSignature {
84 #[serde(with = "serde_bytes")]
85 #[annotate(format = hexstr)]
86 pub r: Vec<u8>,
87 #[serde(with = "serde_bytes")]
88 #[annotate(format = hexstr)]
89 pub s: Vec<u8>,
90}
91
92impl Default for EcdsaRawSignature {
93 fn default() -> Self {
94 Self {
95 r: vec![0u8; 32],
96 s: vec![0u8; 32],
97 }
98 }
99}
100
101impl TryFrom<&[u8]> for EcdsaRawSignature {
102 type Error = Error;
103 fn try_from(value: &[u8]) -> std::result::Result<Self, Self::Error> {
104 if value.len() != Self::SIZE {
105 return Err(Error::InvalidSignature(anyhow!(
106 "bad length: {}",
107 value.len()
108 )));
109 }
110 let mut value = std::io::Cursor::new(value);
111 EcdsaRawSignature::read(&mut value).map_err(Error::InvalidSignature)
112 }
113}
114
115impl EcdsaRawSignature {
116 const SIZE: usize = 64;
117
118 pub fn read(src: &mut impl Read) -> Result<Self> {
119 let mut sig = Self::default();
120 src.read_exact(&mut sig.r)?;
121 src.read_exact(&mut sig.s)?;
122 Ok(sig)
123 }
124
125 pub fn read_from_file(path: &Path) -> Result<EcdsaRawSignature> {
126 let mut file =
127 File::open(path).with_context(|| format!("Failed to read file: {path:?}"))?;
128 let file_size = std::fs::metadata(path)
129 .with_context(|| format!("Failed to get metadata for {path:?}"))?
130 .len();
131
132 let raw_size = Self::SIZE as u64;
133 if file_size == raw_size {
134 EcdsaRawSignature::read(&mut file)
136 } else {
137 let mut data = Vec::<u8>::new();
138
139 file.read_to_end(&mut data)
140 .with_context(|| format!("Failed to read {path:?}"))?;
141
142 EcdsaRawSignature::from_der(&data)
145 .or_else(|_| EcdsaRawSignature::from_pem(&data))
146 .with_context(|| format!("Failed parsing {path:?}"))
147 }
148 }
149
150 pub fn write(&self, dest: &mut impl Write) -> Result<usize> {
151 ensure!(
152 self.r.len() == 32,
153 Error::InvalidSignature(anyhow!("bad r length: {}", self.r.len()))
154 );
155 ensure!(
156 self.s.len() == 32,
157 Error::InvalidSignature(anyhow!("bad s length: {}", self.s.len()))
158 );
159 dest.write_all(&self.r)?;
160 dest.write_all(&self.s)?;
161 Ok(64)
162 }
163
164 pub fn to_vec(&self) -> Result<Vec<u8>> {
165 let mut sig = Vec::new();
166 self.write(&mut sig)?;
167 Ok(sig)
168 }
169
170 pub fn is_empty(&self) -> bool {
171 self.r.iter().all(|&v| v == 0) && self.s.iter().all(|&v| v == 0)
172 }
173
174 fn from_der(data: &[u8]) -> Result<EcdsaRawSignature> {
175 let sig = Signature::<NistP256>::from_der(data).with_context(|| "Failed to parse DER")?;
176
177 let mut r: Vec<u8> = sig.r().to_bytes().to_vec();
184 let mut s: Vec<u8> = sig.s().to_bytes().to_vec();
185
186 r.reverse();
188 s.reverse();
189
190 r.resize(32, 0u8);
191 s.resize(32, 0u8);
192
193 Ok(EcdsaRawSignature { r, s })
194 }
195
196 fn from_pem(data: &[u8]) -> Result<EcdsaRawSignature> {
197 let _ = pem_rfc7468::decode_label(data)?;
199 let mut buf = Vec::new();
200 let result = Decoder::new(data);
201 match result {
202 Ok(mut decoder) => decoder.decode_to_end(&mut buf)?,
203 _ => {
204 let cleaned_data = clean_pem_bytes_for_parsing(data)?;
205 let mut decoder = Decoder::new(&cleaned_data)?;
206 decoder.decode_to_end(&mut buf)?
207 }
208 };
209 Self::from_der(buf.as_slice())
210 }
211}
212
213impl EcdsaPublicKey {
214 pub fn save(&self, path: impl AsRef<Path>) -> Result<()> {
215 self.key.write_public_key_der_file(path)?;
216 Ok(())
217 }
218
219 pub fn load(path: impl AsRef<Path>) -> Result<Self> {
220 let key = VerifyingKey::read_public_key_der_file(path)?;
221 Ok(Self { key })
222 }
223
224 pub fn verify(&self, digest: &Sha256Digest, signature: &EcdsaRawSignature) -> Result<()> {
225 let mut bytes = signature.to_vec()?;
226 let half = bytes.len() / 2;
227 bytes[..half].reverse();
231 bytes[half..].reverse();
232 let signature = Signature::from_slice(&bytes)?;
233 self.key.verify_prehash(digest.as_ref(), &signature)?;
234 Ok(())
235 }
236}
237
238impl TryFrom<&EcdsaRawPublicKey> for EcdsaPublicKey {
239 type Error = Error;
240 fn try_from(v: &EcdsaRawPublicKey) -> Result<Self, Self::Error> {
241 let mut x = v.x.clone();
242 let mut y = v.y.clone();
243
244 x.reverse();
245 y.reverse();
246
247 let key = VerifyingKey::from_encoded_point(&p256::EncodedPoint::from_affine_coordinates(
248 &GenericArray::from(<[u8; 32]>::try_from(x.as_slice()).unwrap()),
249 &GenericArray::from(<[u8; 32]>::try_from(y.as_slice()).unwrap()),
250 false,
251 ))
252 .map_err(|e| Error::Other(anyhow!(e)))
253 .context("Failed to create verifying key from raw public key")?;
254 Ok(Self { key })
255 }
256}
257
258#[derive(Debug, Deserialize, Annotate, PartialEq)]
259pub struct EcdsaRawPublicKey {
260 #[serde(with = "serde_bytes")]
261 #[annotate(format = hexstr)]
262 pub x: Vec<u8>,
263 #[serde(with = "serde_bytes")]
264 #[annotate(format = hexstr)]
265 pub y: Vec<u8>,
266}
267
268impl Default for EcdsaRawPublicKey {
269 fn default() -> Self {
270 Self {
271 x: vec![0u8; 32],
272 y: vec![0u8; 32],
273 }
274 }
275}
276
277impl TryFrom<&EcdsaPublicKey> for EcdsaRawPublicKey {
278 type Error = Error;
279 fn try_from(v: &EcdsaPublicKey) -> Result<Self, Self::Error> {
280 let point = v.key.to_encoded_point(false);
281 let mut x = point.x().unwrap().as_slice().to_vec();
284 let mut y = point.y().unwrap().as_slice().to_vec();
285 x.reverse();
286 y.reverse();
287 Ok(EcdsaRawPublicKey { x, y })
288 }
289}
290
291impl TryFrom<EcdsaPublicKey> for EcdsaRawPublicKey {
292 type Error = Error;
293 fn try_from(v: EcdsaPublicKey) -> Result<Self, Self::Error> {
294 EcdsaRawPublicKey::try_from(&v)
295 }
296}
297
298impl FromStr for EcdsaRawPublicKey {
299 type Err = Error;
300 fn from_str(s: &str) -> Result<Self, Self::Err> {
301 let key = EcdsaPublicKey::load(s)
302 .with_context(|| format!("Failed to load {s}"))
303 .map_err(Error::Other)?;
304 EcdsaRawPublicKey::try_from(&key)
305 }
306}
307
308impl EcdsaRawPublicKey {
309 pub const SIZE: usize = 32 + 32;
310 pub fn read(src: &mut impl Read) -> Result<Self> {
311 let mut key = Self::default();
312 src.read_exact(&mut key.x)?;
313 src.read_exact(&mut key.y)?;
314 Ok(key)
315 }
316 pub fn write(&self, dest: &mut impl Write) -> Result<()> {
317 ensure!(
318 self.x.len() == 32,
319 Error::InvalidPublicKey(anyhow!("bad x length: {}", self.x.len()))
320 );
321 ensure!(
322 self.y.len() == 32,
323 Error::InvalidPublicKey(anyhow!("bad y length: {}", self.y.len()))
324 );
325 dest.write_all(&self.x)?;
326 dest.write_all(&self.y)?;
327 Ok(())
328 }
329}