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