1use crate::errors::{CoseError, CoseResult, CoseResultWithRet};
3use crate::keys;
4use openssl::aes::{unwrap_key, wrap_key, AesKey};
5use openssl::bn::{BigNum, BigNumContext};
6use openssl::cipher;
7use openssl::cipher_ctx::CipherCtx;
8use openssl::derive::Deriver;
9use openssl::ec::{EcGroup, EcKey, EcPoint};
10use openssl::ecdsa::EcdsaSig;
11use openssl::hash::{hash, MessageDigest};
12use openssl::md::Md;
13use openssl::nid::Nid;
14use openssl::pkey::{Id, PKey, Private, Public};
15use openssl::pkey_ctx::{HkdfMode, PkeyCtx};
16use openssl::rsa::{Padding, Rsa};
17use openssl::sign::{RsaPssSaltlen, Signer, Verifier};
18use openssl::stack::Stack;
19use openssl::symm::{decrypt_aead, encrypt as encr, encrypt_aead, Cipher};
20use openssl::x509::{store::X509StoreBuilder, X509StoreContext, X509};
21use rand::Rng;
22
23pub const ES256: i32 = -7;
25pub const ES256K: i32 = -47;
26pub const ES384: i32 = -35;
27pub const ES512: i32 = -36;
28pub const EDDSA: i32 = -8;
29pub const PS512: i32 = -39;
30pub const PS384: i32 = -38;
31pub const PS256: i32 = -37;
32pub(crate) const SIGNING_ALGS: [i32; 8] = [ES256, ES384, ES512, EDDSA, PS256, PS384, PS512, ES256K];
33pub(crate) const SIGNING_ALGS_NAMES: [&str; 8] = [
34 "ES256", "ES384", "ES512", "EDDSA", "PS256", "PS384", "PS512", "ES256K",
35];
36
37pub const A128GCM: i32 = 1;
39pub const A192GCM: i32 = 2;
40pub const A256GCM: i32 = 3;
41pub const CHACHA20: i32 = 24;
42pub const AES_CCM_16_64_128: i32 = 10;
43pub const AES_CCM_16_64_256: i32 = 11;
44pub const AES_CCM_64_64_128: i32 = 12;
45pub const AES_CCM_64_64_256: i32 = 13;
46pub const AES_CCM_16_128_128: i32 = 30;
47pub const AES_CCM_16_128_256: i32 = 31;
48pub const AES_CCM_64_128_128: i32 = 32;
49pub const AES_CCM_64_128_256: i32 = 33;
50pub(crate) const ENCRYPT_ALGS: [i32; 12] = [
51 A128GCM,
52 A192GCM,
53 A256GCM,
54 CHACHA20,
55 AES_CCM_16_64_128,
56 AES_CCM_16_64_256,
57 AES_CCM_64_64_128,
58 AES_CCM_64_64_256,
59 AES_CCM_16_128_128,
60 AES_CCM_16_128_256,
61 AES_CCM_64_128_128,
62 AES_CCM_64_128_256,
63];
64pub(crate) const ENCRYPT_ALGS_NAMES: [&str; 12] = [
65 "A128GCM",
66 "A192GCM",
67 "A256GCM",
68 "ChaCha20/Poly1305",
69 "AES-CCM-16-64-128",
70 "AES-CCM-16-64-256",
71 "AES-CCM-64-64-128",
72 "AES-CCM-64-64-256",
73 "AES-CCM-16-128-128",
74 "AES-CCM-16-128-256",
75 "AES-CCM-64-128-128",
76 "AES-CCM-64-128-256",
77];
78
79pub const HMAC_256_64: i32 = 4;
81pub const HMAC_256_256: i32 = 5;
82pub const HMAC_384_384: i32 = 6;
83pub const HMAC_512_512: i32 = 7;
84pub const AES_MAC_128_64: i32 = 14;
85pub const AES_MAC_256_64: i32 = 15;
86pub const AES_MAC_128_128: i32 = 25;
87pub const AES_MAC_256_128: i32 = 26;
88pub(crate) const MAC_ALGS_NAMES: [&str; 8] = [
89 "HMAC 256/64",
90 "HMAC 256/256",
91 "HMAC 384/384",
92 "HMAC 512/512",
93 "AES-MAC 128/64",
94 "AES-MAC 256/64",
95 "AES-MAC 128/128",
96 "AES-MAC 256/128",
97];
98pub(crate) const MAC_ALGS: [i32; 8] = [
99 HMAC_256_64,
100 HMAC_256_256,
101 HMAC_384_384,
102 HMAC_512_512,
103 AES_MAC_128_64,
104 AES_MAC_256_64,
105 AES_MAC_128_128,
106 AES_MAC_256_128,
107];
108
109pub const SHA_256: i32 = -16;
111pub const HASH_ALGS: [i32; 1] = [SHA_256];
112pub const HASH_ALGS_NAMES: [&str; 1] = ["SHA-256"];
113
114pub const DIRECT: i32 = -6;
118pub const DIRECT_HKDF_SHA_256: i32 = -10;
120pub const DIRECT_HKDF_SHA_512: i32 = -11;
121pub const DIRECT_HKDF_AES_128: i32 = -12;
122pub const DIRECT_HKDF_AES_256: i32 = -13;
123pub const A128KW: i32 = -3;
125pub const A192KW: i32 = -4;
126pub const A256KW: i32 = -5;
127pub const RSA_OAEP_1: i32 = -40;
129pub const RSA_OAEP_256: i32 = -41;
130pub const RSA_OAEP_512: i32 = -42;
131pub const ECDH_ES_HKDF_256: i32 = -25;
133pub const ECDH_ES_HKDF_512: i32 = -26;
134pub const ECDH_SS_HKDF_256: i32 = -27;
135pub const ECDH_SS_HKDF_512: i32 = -28;
136pub const ECDH_ES_A128KW: i32 = -29;
138pub const ECDH_ES_A192KW: i32 = -30;
139pub const ECDH_ES_A256KW: i32 = -31;
140pub const ECDH_SS_A128KW: i32 = -32;
141pub const ECDH_SS_A192KW: i32 = -33;
142pub const ECDH_SS_A256KW: i32 = -34;
143pub(crate) const KEY_DISTRIBUTION_ALGS: [i32; 21] = [
144 DIRECT,
145 DIRECT_HKDF_SHA_256,
146 DIRECT_HKDF_SHA_512,
147 DIRECT_HKDF_AES_128,
148 DIRECT_HKDF_AES_256,
149 A128KW,
150 A192KW,
151 A256KW,
152 RSA_OAEP_1,
153 RSA_OAEP_256,
154 RSA_OAEP_512,
155 ECDH_ES_HKDF_256,
156 ECDH_ES_HKDF_512,
157 ECDH_SS_HKDF_256,
158 ECDH_SS_HKDF_512,
159 ECDH_ES_A128KW,
160 ECDH_ES_A192KW,
161 ECDH_ES_A256KW,
162 ECDH_SS_A128KW,
163 ECDH_SS_A192KW,
164 ECDH_SS_A256KW,
165];
166
167pub(crate) const KEY_DISTRIBUTION_NAMES: [&str; 21] = [
168 "direct",
169 "direct+HKDF-SHA-256",
170 "direct+HKDF-SHA-512",
171 "direct+HKDF-AES-128",
172 "direct+HKDF-AES-256",
173 "A128KW",
174 "A192KW",
175 "A256KW",
176 "RSAES-OAEP w/ RFC 8017 default parameters",
177 "RSAES-OAEP w/ SHA-256",
178 "RSAES-OAEP w/ SHA-512",
179 "ECDH-ES + HKDF-256",
180 "ECDH-ES + HKDF-512",
181 "ECDH-SS + HKDF-256",
182 "ECDH-SS + HKDF-512",
183 "ECDH-ES + A128KW",
184 "ECDH-ES + A192KW",
185 "ECDH-ES + A256KW",
186 "ECDH-SS + A128KW",
187 "ECDH-SS + A192KW",
188 "ECDH-SS + A256KW",
189];
190pub(crate) const ECDH_ALGS: [i32; 10] = [
191 ECDH_ES_HKDF_256,
192 ECDH_ES_HKDF_512,
193 ECDH_SS_HKDF_256,
194 ECDH_SS_HKDF_512,
195 ECDH_ES_A128KW,
196 ECDH_ES_A192KW,
197 ECDH_ES_A256KW,
198 ECDH_SS_A128KW,
199 ECDH_SS_A192KW,
200 ECDH_SS_A256KW,
201];
202const K16_ALGS: [i32; 11] = [
203 A128GCM,
204 CHACHA20,
205 AES_CCM_16_64_128,
206 AES_CCM_64_64_128,
207 AES_CCM_16_128_128,
208 AES_CCM_64_128_128,
209 AES_MAC_128_64,
210 AES_MAC_128_128,
211 ECDH_ES_A128KW,
212 ECDH_SS_A128KW,
213 A128KW,
214];
215const K24_ALGS: [i32; 4] = [A192KW, ECDH_ES_A192KW, ECDH_SS_A192KW, A192GCM];
216const K32_ALGS: [i32; 12] = [
217 A256GCM,
218 AES_CCM_16_64_256,
219 AES_CCM_64_64_256,
220 AES_CCM_16_128_256,
221 AES_CCM_64_128_256,
222 AES_MAC_256_128,
223 AES_MAC_256_64,
224 HMAC_256_64,
225 HMAC_256_256,
226 ECDH_ES_A256KW,
227 ECDH_SS_A256KW,
228 A256KW,
229];
230
231pub(crate) const OKP_ALGS: [i32; 1] = [EDDSA];
232pub(crate) const EC2_ALGS: [i32; 4] = [ES256, ES384, ES512, ES256K];
233pub(crate) const RSA_ALGS: [i32; 3] = [PS256, PS384, PS512];
234pub(crate) const SYMMETRIC_ALGS: [i32; 28] = [
235 A128GCM,
236 A192GCM,
237 A256GCM,
238 CHACHA20,
239 AES_CCM_16_64_128,
240 AES_CCM_16_64_256,
241 AES_CCM_64_64_128,
242 AES_CCM_64_64_256,
243 AES_CCM_16_128_128,
244 AES_CCM_16_128_256,
245 AES_CCM_64_128_128,
246 AES_CCM_64_128_256,
247 HMAC_256_64,
248 HMAC_256_256,
249 HMAC_384_384,
250 HMAC_512_512,
251 AES_MAC_128_64,
252 AES_MAC_256_64,
253 AES_MAC_128_128,
254 AES_MAC_256_128,
255 DIRECT,
256 DIRECT_HKDF_SHA_256,
257 DIRECT_HKDF_SHA_512,
258 DIRECT_HKDF_AES_128,
259 DIRECT_HKDF_AES_256,
260 A128KW,
261 A192KW,
262 A256KW,
263];
264
265pub(crate) const RSA_OAEP: [i32; 3] = [RSA_OAEP_1, RSA_OAEP_256, RSA_OAEP_512];
266pub(crate) const A_KW: [i32; 3] = [A128KW, A192KW, A256KW];
267pub(crate) const D_HA: [i32; 2] = [DIRECT_HKDF_AES_128, DIRECT_HKDF_AES_256];
268pub(crate) const D_HS: [i32; 2] = [DIRECT_HKDF_SHA_256, DIRECT_HKDF_SHA_512];
269pub(crate) const ECDH_H: [i32; 4] = [
270 ECDH_ES_HKDF_256,
271 ECDH_ES_HKDF_512,
272 ECDH_SS_HKDF_256,
273 ECDH_SS_HKDF_512,
274];
275pub(crate) const ECDH_A: [i32; 6] = [
276 ECDH_ES_A128KW,
277 ECDH_ES_A192KW,
278 ECDH_ES_A256KW,
279 ECDH_SS_A128KW,
280 ECDH_SS_A192KW,
281 ECDH_SS_A256KW,
282];
283
284const DER_S2: [u8; 16] = [48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32];
285const DER_S4: [u8; 16] = [48, 71, 2, 1, 0, 48, 5, 6, 3, 43, 101, 113, 4, 59, 4, 57];
286const DER_P2: [u8; 12] = [48, 42, 48, 5, 6, 3, 43, 101, 112, 3, 33, 0];
287const DER_P4: [u8; 12] = [48, 67, 48, 5, 6, 3, 43, 101, 113, 3, 58, 0];
288
289pub fn sign(
291 alg: i32,
292 crv: Option<i32>,
293 key: &Vec<u8>,
294 content: &Vec<u8>,
295) -> CoseResultWithRet<Vec<u8>> {
296 let number = BigNum::from_slice(key.as_slice())?;
297 let group;
298 let message_digest;
299 if [ES256, ES384, ES512].contains(&alg) {
300 if alg == ES256 {
301 message_digest = MessageDigest::sha256();
302 } else if alg == ES384 {
303 message_digest = MessageDigest::sha384();
304 } else {
305 message_digest = MessageDigest::sha512();
306 }
307 let crv = crv.ok_or(CoseError::InvalidCRV())?;
308 if crv == keys::P_256 {
309 group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1)?;
310 } else if crv == keys::P_384 {
311 group = EcGroup::from_curve_name(Nid::SECP384R1)?;
312 } else if crv == keys::P_521 {
313 group = EcGroup::from_curve_name(Nid::SECP521R1)?;
314 } else {
315 return Err(CoseError::InvalidCRV());
316 }
317 } else if alg == ES256K {
318 group = EcGroup::from_curve_name(Nid::SECP256K1)?;
319 message_digest = MessageDigest::sha256();
320 } else if alg == EDDSA {
321 let mut ed_key;
322 let crv = crv.ok_or(CoseError::InvalidCRV())?;
323 if crv == keys::ED25519 {
324 ed_key = DER_S2.to_vec();
325 ed_key.append(&mut key.clone());
326 } else if crv == keys::ED448 {
327 ed_key = DER_S4.to_vec();
328 ed_key.append(&mut key.clone());
329 } else {
330 return Err(CoseError::InvalidCRV());
331 }
332 let key = PKey::private_key_from_der(ed_key.as_slice())?;
333 let mut signer = Signer::new(MessageDigest::null(), &key)?;
334 let size = signer.len()?;
335 let mut s = vec![0; size];
336 signer.sign_oneshot(&mut s, content.as_slice())?;
337 return Ok(s);
338 } else if alg == PS256 {
339 let rsa_key = Rsa::private_key_from_der(key)?;
340 let key = PKey::from_rsa(rsa_key)?;
341 let mut signer = Signer::new(MessageDigest::sha256(), &key)?;
342 signer.set_rsa_padding(Padding::PKCS1_PSS)?;
343 signer.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)?;
344 signer.update(&content)?;
345 return Ok(signer.sign_to_vec()?);
346 } else if alg == PS384 {
347 let rsa_key = Rsa::private_key_from_der(key)?;
348 let key = PKey::from_rsa(rsa_key)?;
349 let mut signer = Signer::new(MessageDigest::sha384(), &key)?;
350 signer.set_rsa_padding(Padding::PKCS1_PSS)?;
351 signer.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)?;
352 signer.update(&content)?;
353 return Ok(signer.sign_to_vec()?);
354 } else if alg == PS512 {
355 let rsa_key = Rsa::private_key_from_der(key)?;
356 let key = PKey::from_rsa(rsa_key)?;
357 let mut signer = Signer::new(MessageDigest::sha512(), &key)?;
358 signer.set_rsa_padding(Padding::PKCS1_PSS)?;
359 signer.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)?;
360 signer.update(&content)?;
361 return Ok(signer.sign_to_vec()?);
362 } else {
363 return Err(CoseError::InvalidAlg());
364 }
365 let size: i32 = key.len() as i32;
366 let ec_key = EcKey::from_private_components(&group, &number, &EcPoint::new(&group).unwrap())?;
367 let final_key = PKey::from_ec_key(ec_key)?;
368 let mut signer = Signer::new(message_digest, &final_key)?;
369 signer.update(content.as_slice())?;
370 let der_sig = signer.sign_to_vec()?;
371 let priv_comp = EcdsaSig::from_der(&der_sig)?;
372 let mut s = priv_comp.r().to_vec_padded(size)?;
373 s.append(&mut priv_comp.s().to_vec_padded(size)?);
374 Ok(s)
375}
376
377pub fn verify(
379 alg: i32,
380 crv: Option<i32>,
381 key: &Vec<u8>,
382 content: &Vec<u8>,
383 signature: &Vec<u8>,
384) -> CoseResultWithRet<bool> {
385 let group;
386 let message_digest;
387 let mut ctx = BigNumContext::new()?;
388 let size: usize;
389 if key[0] == 3 {
390 size = key.len() - 1;
391 } else {
392 size = (key.len() - 1) / 2;
393 }
394 if [ES256, ES384, ES512].contains(&alg) {
395 if alg == ES256 {
396 message_digest = MessageDigest::sha256();
397 } else if alg == ES384 {
398 message_digest = MessageDigest::sha384();
399 } else {
400 message_digest = MessageDigest::sha512();
401 }
402 let crv = crv.ok_or(CoseError::InvalidCRV())?;
403 if crv == keys::P_256 {
404 group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1)?;
405 } else if crv == keys::P_384 {
406 group = EcGroup::from_curve_name(Nid::SECP384R1)?;
407 } else if crv == keys::P_521 {
408 group = EcGroup::from_curve_name(Nid::SECP521R1)?;
409 } else {
410 return Err(CoseError::InvalidCRV());
411 }
412 } else if alg == ES256K {
413 group = EcGroup::from_curve_name(Nid::SECP256K1)?;
414 message_digest = MessageDigest::sha256();
415 } else if alg == EDDSA {
416 let mut ed_key;
417 let crv = crv.ok_or(CoseError::InvalidCRV())?;
418 if crv == keys::ED25519 {
419 ed_key = DER_P2.to_vec();
420 ed_key.append(&mut key.clone());
421 } else if crv == keys::ED448 {
422 ed_key = DER_P4.to_vec();
423 ed_key.append(&mut key.clone());
424 } else {
425 return Err(CoseError::InvalidCRV());
426 }
427 let ec_public_key = PKey::public_key_from_der(ed_key.as_slice())?;
428 let mut verifier = Verifier::new(MessageDigest::null(), &ec_public_key)?;
429 return Ok(verifier.verify_oneshot(&signature, &content)?);
430 } else if alg == PS256 {
431 let rsa_key = Rsa::public_key_from_der(key)?;
432 let key = PKey::from_rsa(rsa_key)?;
433 let mut verifier = Verifier::new(MessageDigest::sha256(), &key)?;
434 verifier.set_rsa_padding(Padding::PKCS1_PSS)?;
435 verifier.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)?;
436 verifier.update(&content)?;
437 return Ok(verifier.verify(&signature)?);
438 } else if alg == PS384 {
439 let rsa_key = Rsa::public_key_from_der(key)?;
440 let key = PKey::from_rsa(rsa_key)?;
441 let mut verifier = Verifier::new(MessageDigest::sha384(), &key)?;
442 verifier.set_rsa_padding(Padding::PKCS1_PSS)?;
443 verifier.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)?;
444 verifier.update(&content)?;
445 return Ok(verifier.verify(&signature)?);
446 } else if alg == PS512 {
447 let rsa_key = Rsa::public_key_from_der(key)?;
448 let key = PKey::from_rsa(rsa_key)?;
449 let mut verifier = Verifier::new(MessageDigest::sha512(), &key)?;
450 verifier.set_rsa_padding(Padding::PKCS1_PSS)?;
451 verifier.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)?;
452 verifier.update(&content)?;
453 return Ok(verifier.verify(&signature)?);
454 } else {
455 return Err(CoseError::InvalidAlg());
456 }
457 let point = EcPoint::from_bytes(&group, &key, &mut ctx)?;
458 let ec_key = EcKey::from_public_key(&group, &point)?;
459 let final_key = PKey::from_ec_key(ec_key)?;
460 let mut verifier = Verifier::new(message_digest, &final_key)?;
461 verifier.update(&content)?;
462 let s = EcdsaSig::from_private_components(
463 BigNum::from_slice(&signature[..size])?,
464 BigNum::from_slice(&signature[size..])?,
465 )?;
466 Ok(verifier.verify(&s.to_der()?)?)
467}
468
469pub(crate) fn mac(alg: i32, key: &Vec<u8>, content: &Vec<u8>) -> CoseResultWithRet<Vec<u8>> {
470 let size;
471 if [
472 AES_MAC_128_64,
473 AES_MAC_256_64,
474 AES_MAC_128_128,
475 AES_MAC_256_128,
476 ]
477 .contains(&alg)
478 {
479 let mut padded: Vec<u8> = content.to_vec();
480 if padded.len() % 16 != 0 {
481 padded.append(&mut vec![0; 16 - (padded.len() % 16)]);
482 }
483 let cipher;
484 let index = padded.len() - 16;
485 if alg == AES_MAC_128_64 {
486 size = 8;
487 cipher = Cipher::aes_128_cbc()
488 } else if alg == AES_MAC_256_64 {
489 size = 8;
490 cipher = Cipher::aes_256_cbc()
491 } else if alg == AES_MAC_128_128 {
492 size = 16;
493 cipher = Cipher::aes_128_cbc()
494 } else {
495 size = 16;
496 cipher = Cipher::aes_256_cbc()
497 }
498 let s = encr(cipher, key, Some(&[0; 16]), &padded)?;
499 Ok(s[index..index + size].to_vec())
500 } else {
501 let k;
502 let message_digest;
503
504 if alg == HMAC_256_64 {
505 k = PKey::hmac(key.as_slice())?;
506 message_digest = MessageDigest::sha256();
507 size = 8;
508 } else if alg == HMAC_256_256 {
509 k = PKey::hmac(key.as_slice())?;
510 message_digest = MessageDigest::sha256();
511 size = 32;
512 } else if alg == HMAC_384_384 {
513 k = PKey::hmac(key.as_slice())?;
514 message_digest = MessageDigest::sha384();
515 size = 48;
516 } else if alg == HMAC_512_512 {
517 k = PKey::hmac(key.as_slice())?;
518 message_digest = MessageDigest::sha512();
519 size = 64;
520 } else {
521 return Err(CoseError::InvalidAlg());
522 }
523 let mut signer = Signer::new(message_digest, &k)?;
524 signer.update(content.as_slice())?;
525 let mut s = signer.sign_to_vec()?;
526 s.truncate(size);
527 Ok(s)
528 }
529}
530
531pub(crate) fn mac_verify(
532 alg: i32,
533 key: &Vec<u8>,
534 content: &Vec<u8>,
535 signature: &Vec<u8>,
536) -> CoseResultWithRet<bool> {
537 let size;
538 if [
539 AES_MAC_128_64,
540 AES_MAC_256_64,
541 AES_MAC_128_128,
542 AES_MAC_256_128,
543 ]
544 .contains(&alg)
545 {
546 let mut padded: Vec<u8> = content.to_vec();
547 if padded.len() % 16 != 0 {
548 padded.append(&mut vec![0; 16 - (padded.len() % 16)]);
549 }
550 let cipher;
551 let index = padded.len() - 16;
552 if alg == AES_MAC_128_64 {
553 size = 8;
554 cipher = Cipher::aes_128_cbc()
555 } else if alg == AES_MAC_256_64 {
556 size = 8;
557 cipher = Cipher::aes_256_cbc()
558 } else if alg == AES_MAC_128_128 {
559 size = 16;
560 cipher = Cipher::aes_128_cbc()
561 } else {
562 size = 16;
563 cipher = Cipher::aes_256_cbc()
564 }
565 let s = encr(cipher, key, Some(&[0; 16]), &padded)?;
566 Ok(s[index..index + size].to_vec() == *signature)
567 } else {
568 let k;
569 let message_digest;
570
571 if alg == HMAC_256_64 {
572 k = PKey::hmac(key.as_slice())?;
573 message_digest = MessageDigest::sha256();
574 size = 8;
575 } else if alg == HMAC_256_256 {
576 k = PKey::hmac(key.as_slice())?;
577 message_digest = MessageDigest::sha256();
578 size = 32;
579 } else if alg == HMAC_384_384 {
580 k = PKey::hmac(key.as_slice())?;
581 message_digest = MessageDigest::sha384();
582 size = 48;
583 } else if alg == HMAC_512_512 {
584 k = PKey::hmac(key.as_slice())?;
585 message_digest = MessageDigest::sha512();
586 size = 64;
587 } else {
588 return Err(CoseError::InvalidAlg());
589 }
590 let mut verifier = Signer::new(message_digest, &k)?;
591 verifier.update(content.as_slice())?;
592 let s = verifier.sign_to_vec()?;
593 Ok(s[..size].to_vec() == *signature)
594 }
595}
596pub(crate) fn encrypt(
597 alg: i32,
598 key: &Vec<u8>,
599 iv: &Vec<u8>,
600 payload: &Vec<u8>,
601 aead: &Vec<u8>,
602) -> CoseResultWithRet<Vec<u8>> {
603 if [
604 AES_CCM_16_64_128,
605 AES_CCM_16_64_256,
606 AES_CCM_64_64_128,
607 AES_CCM_64_64_256,
608 AES_CCM_16_128_128,
609 AES_CCM_16_128_256,
610 AES_CCM_64_128_128,
611 AES_CCM_64_128_256,
612 ]
613 .contains(&alg)
614 {
615 let cipher;
616 let tag_len;
617 if alg == AES_CCM_16_64_128 {
618 tag_len = 8;
619 cipher = cipher::Cipher::aes_128_ccm();
620 } else if alg == AES_CCM_16_64_256 {
621 tag_len = 8;
622 cipher = cipher::Cipher::aes_256_ccm();
623 } else if alg == AES_CCM_64_64_128 {
624 tag_len = 8;
625 cipher = cipher::Cipher::aes_128_ccm();
626 } else if alg == AES_CCM_64_64_256 {
627 tag_len = 8;
628 cipher = cipher::Cipher::aes_256_ccm();
629 } else if alg == AES_CCM_16_128_128 {
630 tag_len = 16;
631 cipher = cipher::Cipher::aes_128_ccm();
632 } else if alg == AES_CCM_16_128_256 {
633 tag_len = 16;
634 cipher = cipher::Cipher::aes_256_ccm();
635 } else if alg == AES_CCM_64_128_128 {
636 tag_len = 16;
637 cipher = cipher::Cipher::aes_128_ccm();
638 } else {
639 tag_len = 16;
640 cipher = cipher::Cipher::aes_256_ccm();
641 }
642 let mut ctx = CipherCtx::new()?;
643 ctx.encrypt_init(Some(cipher), None, None)?;
644
645 ctx.set_tag_length(tag_len)?;
646 ctx.set_key_length(key.len())?;
647 ctx.set_iv_length(iv.len())?;
648 ctx.encrypt_init(None, Some(&key), Some(&iv))?;
649
650 let mut out = vec![0; payload.len() + cipher.block_size()];
651
652 ctx.set_data_len(payload.len())?;
653
654 ctx.cipher_update(&aead, None)?;
655 let count = ctx.cipher_update(&payload, Some(&mut out))?;
656 let rest = ctx.cipher_final(&mut out[count..])?;
657 out.truncate(count + rest);
658 Ok(out)
659 } else {
660 let mut tag: [u8; 16] = [0; 16];
661 let cipher;
662 if alg == A128GCM {
663 cipher = Cipher::aes_128_gcm();
664 } else if alg == A192GCM {
665 cipher = Cipher::aes_192_gcm();
666 } else if alg == A256GCM {
667 cipher = Cipher::aes_256_gcm();
668 } else if alg == CHACHA20 {
669 cipher = Cipher::chacha20_poly1305();
670 } else {
671 return Err(CoseError::InvalidAlg());
672 }
673 let mut ciphertext = encrypt_aead(cipher, key, Some(iv), aead, payload, &mut tag)?;
674 ciphertext.append(&mut tag.to_vec());
675 Ok(ciphertext)
676 }
677}
678
679pub(crate) fn decrypt(
680 alg: i32,
681 key: &Vec<u8>,
682 iv: &Vec<u8>,
683 ciphertext: &Vec<u8>,
684 aead: &Vec<u8>,
685) -> CoseResultWithRet<Vec<u8>> {
686 if [
687 AES_CCM_16_64_128,
688 AES_CCM_16_64_256,
689 AES_CCM_64_64_128,
690 AES_CCM_64_64_256,
691 AES_CCM_16_128_128,
692 AES_CCM_16_128_256,
693 AES_CCM_64_128_128,
694 AES_CCM_64_128_256,
695 ]
696 .contains(&alg)
697 {
698 let cipher;
699 let tag_len;
700 if alg == AES_CCM_16_64_128 {
701 tag_len = 8;
702 cipher = cipher::Cipher::aes_128_ccm();
703 } else if alg == AES_CCM_16_64_256 {
704 tag_len = 8;
705 cipher = cipher::Cipher::aes_256_ccm();
706 } else if alg == AES_CCM_64_64_128 {
707 tag_len = 8;
708 cipher = cipher::Cipher::aes_128_ccm();
709 } else if alg == AES_CCM_64_64_256 {
710 tag_len = 8;
711 cipher = cipher::Cipher::aes_256_ccm();
712 } else if alg == AES_CCM_16_128_128 {
713 tag_len = 16;
714 cipher = cipher::Cipher::aes_128_ccm();
715 } else if alg == AES_CCM_16_128_256 {
716 tag_len = 16;
717 cipher = cipher::Cipher::aes_256_ccm();
718 } else if alg == AES_CCM_64_128_128 {
719 tag_len = 16;
720 cipher = cipher::Cipher::aes_128_ccm();
721 } else {
722 tag_len = 16;
723 cipher = cipher::Cipher::aes_256_ccm();
724 }
725 let offset = ciphertext.len() - tag_len;
726 let data = ciphertext[..offset].to_vec();
727 let tag = ciphertext[offset..].to_vec();
728 let mut ctx = CipherCtx::new()?;
729 ctx.decrypt_init(Some(cipher), None, None)?;
730
731 ctx.set_tag_length(tag_len)?;
732 ctx.set_key_length(key.len())?;
733 ctx.set_iv_length(iv.len())?;
734 ctx.decrypt_init(None, Some(&key), Some(&iv))?;
735
736 let mut out = vec![0; data.len() + cipher.block_size()];
737
738 ctx.set_tag(&tag)?;
739 ctx.set_data_len(data.len())?;
740
741 ctx.cipher_update(&aead, None)?;
742 let count = ctx.cipher_update(&data, Some(&mut out))?;
743 out.truncate(count);
744 Ok(out)
745 } else {
746 let offset = ciphertext.len() - 16;
747 let cipher;
748 if alg == A128GCM {
749 cipher = Cipher::aes_128_gcm();
750 } else if alg == A192GCM {
751 cipher = Cipher::aes_192_gcm();
752 } else if alg == A256GCM {
753 cipher = Cipher::aes_256_gcm();
754 } else if alg == CHACHA20 {
755 cipher = Cipher::chacha20_poly1305();
756 } else {
757 return Err(CoseError::InvalidAlg());
758 }
759 Ok(decrypt_aead(
760 cipher,
761 key,
762 Some(iv),
763 aead,
764 &ciphertext[..offset],
765 &ciphertext[offset..],
766 )?)
767 }
768}
769
770pub(crate) fn aes_key_wrap(
771 key: &Vec<u8>,
772 size: usize,
773 cek: &Vec<u8>,
774) -> CoseResultWithRet<Vec<u8>> {
775 let aes_key = AesKey::new_encrypt(&key)?;
776 let mut ciphertext = vec![0u8; (size + 8).into()];
777 wrap_key(&aes_key, None, &mut ciphertext, cek)?;
778 Ok(ciphertext)
779}
780
781pub(crate) fn aes_key_unwrap(
782 key: &Vec<u8>,
783 size: usize,
784 cek: &Vec<u8>,
785) -> CoseResultWithRet<Vec<u8>> {
786 let aes_key = AesKey::new_decrypt(&key)?;
787 let mut orig_key = vec![0u8; size];
788 unwrap_key(&aes_key, None, &mut orig_key, cek)?;
789 Ok(orig_key)
790}
791pub(crate) fn rsa_oaep_enc(
792 key: &Vec<u8>,
793 size: usize,
794 cek: &Vec<u8>,
795 alg: &i32,
796) -> CoseResultWithRet<Vec<u8>> {
797 let rsa_key = PKey::public_key_from_der(key)?;
798 let mut enc = PkeyCtx::new(&rsa_key)?;
799 enc.encrypt_init()?;
800 enc.set_rsa_padding(Padding::PKCS1_OAEP)?;
801 if *alg == RSA_OAEP_1 {
802 enc.set_rsa_oaep_md(Md::sha1())?;
803 } else if *alg == RSA_OAEP_256 {
804 enc.set_rsa_oaep_md(Md::sha256())?;
805 } else if *alg == RSA_OAEP_512 {
806 enc.set_rsa_oaep_md(Md::sha512())?;
807 }
808 let mut out: Vec<u8> = Vec::new();
809 enc.encrypt_to_vec(cek, &mut out)?;
810 Ok(out[..size].to_vec())
811}
812
813pub(crate) fn rsa_oaep_dec(
814 key: &Vec<u8>,
815 size: usize,
816 cek: &Vec<u8>,
817 alg: &i32,
818) -> CoseResultWithRet<Vec<u8>> {
819 let rsa_key = PKey::private_key_from_der(key)?;
820 let mut enc = PkeyCtx::new(&rsa_key)?;
821 enc.decrypt_init()?;
822 enc.set_rsa_padding(Padding::PKCS1_OAEP)?;
823 if *alg == RSA_OAEP_1 {
824 enc.set_rsa_oaep_md(Md::sha1())?;
825 } else if *alg == RSA_OAEP_256 {
826 enc.set_rsa_oaep_md(Md::sha256())?;
827 } else if *alg == RSA_OAEP_512 {
828 enc.set_rsa_oaep_md(Md::sha512())?;
829 }
830 let mut out: Vec<u8> = Vec::new();
831 enc.decrypt_to_vec(cek, &mut out)?;
832 Ok(out[..size].to_vec())
833}
834
835pub(crate) fn thumbprint(cert: &Vec<u8>, alg: &i32) -> CoseResultWithRet<Vec<u8>> {
836 if *alg == SHA_256 {
837 let digest = hash(MessageDigest::sha256(), cert)?;
838 Ok(digest.to_vec())
839 } else {
840 Err(CoseError::InvalidAlg())
841 }
842}
843
844pub(crate) fn verify_thumbprint(cert: &Vec<u8>, thumbprint: &Vec<u8>, alg: &i32) -> CoseResult {
845 if *alg == SHA_256 {
846 let digest = hash(MessageDigest::sha256(), &cert)?;
847 assert_eq!(digest.to_vec(), *thumbprint);
848 } else {
849 return Err(CoseError::InvalidAlg());
850 }
851 Ok(())
852}
853
854pub(crate) fn verify_chain(chain: &Vec<Vec<u8>>) -> CoseResult {
855 let stack = Stack::new()?;
856 for i in (1..chain.len()).rev() {
857 let cert = X509::from_der(&chain[i])?;
858 let to_ver = X509::from_der(&chain[i - 1])?;
859 let mut store_bldr = X509StoreBuilder::new()?;
860 store_bldr.add_cert(cert)?;
861 let store = store_bldr.build();
862 let mut context = X509StoreContext::new()?;
863
864 if !context.init(&store, &to_ver, &stack, |c| c.verify_cert())? {
865 return Err(CoseError::InvalidKeyChain());
866 }
867 }
868 Ok(())
869}
870
871pub(crate) fn ecdh_derive_key(
872 crv_rec: Option<i32>,
873 crv_send: Option<i32>,
874 receiver_key: &Vec<u8>,
875 sender_key: &Vec<u8>,
876) -> CoseResultWithRet<Vec<u8>> {
877 let pkey_rec: PKey<Public>;
878 let pkey_send: PKey<Private>;
879 if crv_rec != None {
880 let crv = crv_rec.unwrap();
881 if [keys::X448, keys::X25519].contains(&crv) {
882 let id_pkey;
883 if crv == keys::X448 {
884 id_pkey = Id::X448;
885 } else {
886 id_pkey = Id::X25519;
887 }
888 pkey_rec = PKey::public_key_from_raw_bytes(receiver_key, id_pkey)?;
889 } else {
890 let mut group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1)?;
891 if crv == keys::P_256 {
892 group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1)?;
893 } else if crv == keys::P_384 {
894 group = EcGroup::from_curve_name(Nid::SECP384R1)?;
895 } else if crv == keys::P_521 {
896 group = EcGroup::from_curve_name(Nid::SECP521R1)?;
897 }
898 let mut ctx = BigNumContext::new()?;
899 let point = EcPoint::from_bytes(&group, receiver_key, &mut ctx)?;
900 pkey_rec = PKey::from_ec_key(EcKey::from_public_key(&group, &point)?)?;
901 }
902 } else {
903 let x5 = X509::from_der(&receiver_key)?;
904 pkey_rec = x5.public_key()?;
905 }
906
907 if crv_send != None {
908 let crv = crv_send.unwrap();
909 if [keys::X448, keys::X25519].contains(&crv) {
910 let id_pkey;
911 if crv == keys::X448 {
912 id_pkey = Id::X448;
913 } else {
914 id_pkey = Id::X25519;
915 }
916 pkey_send = PKey::private_key_from_raw_bytes(sender_key, id_pkey)?;
917 } else {
918 let number = BigNum::from_slice(&sender_key)?;
919 let mut group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1)?;
920 if crv == keys::P_256 {
921 group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1)?;
922 } else if crv == keys::P_384 {
923 group = EcGroup::from_curve_name(Nid::SECP384R1)?;
924 } else if crv == keys::P_521 {
925 group = EcGroup::from_curve_name(Nid::SECP521R1)?;
926 }
927 pkey_send = PKey::from_ec_key(EcKey::from_private_components(
928 &group,
929 &number,
930 &EcPoint::new(&group).unwrap(),
931 )?)?;
932 }
933 } else {
934 pkey_send = PKey::private_key_from_der(sender_key)?;
935 }
936 let mut deriver = Deriver::new(&pkey_send)?;
937 deriver.set_peer(&pkey_rec)?;
938 Ok(deriver.derive_to_vec()?)
939}
940
941pub(crate) fn hkdf(
942 length: usize,
943 ikm: &Vec<u8>,
944 salt_input: Option<&Vec<u8>>,
945 info_input: &mut Vec<u8>,
946 alg: i32,
947) -> CoseResultWithRet<Vec<u8>> {
948 if [DIRECT_HKDF_AES_128, DIRECT_HKDF_AES_256].contains(&alg) {
949 let mut t = Vec::new();
950 let mut okm = Vec::new();
951 let mut i = 0;
952 while okm.len() < length {
953 i += 1;
954 let mut info_tmp = info_input.clone();
955 t.append(&mut info_tmp);
956 t.append(&mut vec![i]);
957 let mut padded: Vec<u8> = t;
958 if padded.len() % 16 != 0 {
959 padded.append(&mut vec![0; 16 - (padded.len() % 16)]);
960 }
961 let cipher;
962 let cipher_size;
963 if alg == DIRECT_HKDF_AES_128 {
964 cipher = Cipher::aes_128_cbc();
965 cipher_size = 16;
966 } else {
967 cipher = Cipher::aes_256_cbc();
968 cipher_size = 32;
969 }
970 let index = padded.len() - 16;
971 let s = encr(cipher, &ikm, None, &padded).unwrap();
972 t = s[index..index + 16].to_vec();
973 let mut temp = t.clone();
974 okm.append(&mut temp);
975 }
976 return Ok(okm[..length].to_vec());
977 }
978
979 let mut digest = Md::sha256();
980 if [DIRECT_HKDF_SHA_512, ECDH_ES_HKDF_512, ECDH_SS_HKDF_512].contains(&alg) {
981 digest = Md::sha512();
982 }
983 let salt = match salt_input {
984 Some(v) => v.to_vec(),
985 None => vec![0; length],
986 };
987 let mut ctx = PkeyCtx::new_id(Id::HKDF)?;
988 ctx.derive_init()?;
989 ctx.set_hkdf_md(&digest)?;
990 ctx.set_hkdf_key(ikm)?;
991 ctx.set_hkdf_salt(&salt)?;
992 ctx.add_hkdf_info(info_input)?;
993 let mut out = vec![0; length];
994 ctx.derive(Some(&mut out))?;
995 Ok(out)
996}
997
998pub(crate) fn get_cek_size(alg: &i32) -> CoseResultWithRet<usize> {
999 if K16_ALGS.contains(alg) {
1000 Ok(16)
1001 } else if K32_ALGS.contains(alg) {
1002 Ok(32)
1003 } else if K24_ALGS.contains(alg) {
1004 Ok(24)
1005 } else if HMAC_384_384 == *alg {
1006 Ok(48)
1007 } else if HMAC_512_512 == *alg {
1008 Ok(64)
1009 } else {
1010 Err(CoseError::InvalidAlg())
1011 }
1012}
1013pub(crate) fn gen_random_key(alg: &i32) -> CoseResultWithRet<Vec<u8>> {
1014 if K16_ALGS.contains(alg) {
1015 Ok(rand::thread_rng().gen::<[u8; 16]>().to_vec())
1016 } else if K32_ALGS.contains(alg) {
1017 Ok(rand::thread_rng().gen::<[u8; 32]>().to_vec())
1018 } else if K24_ALGS.contains(alg) {
1019 Ok(rand::thread_rng().gen::<[u8; 24]>().to_vec())
1020 } else if HMAC_384_384 == *alg {
1021 let mut out = rand::thread_rng().gen::<[u8; 32]>().to_vec();
1022 out.append(&mut rand::thread_rng().gen::<[u8; 16]>().to_vec());
1023 Ok(out)
1024 } else if HMAC_512_512 == *alg {
1025 let mut out = rand::thread_rng().gen::<[u8; 32]>().to_vec();
1026 out.append(&mut rand::thread_rng().gen::<[u8; 32]>().to_vec());
1027 Ok(out)
1028 } else {
1029 Err(CoseError::InvalidAlg())
1030 }
1031}
1032
1033pub(crate) fn get_iv_size(alg: &i32) -> CoseResultWithRet<usize> {
1034 if [A128GCM, A192GCM, A256GCM, CHACHA20].contains(alg) {
1035 Ok(12)
1036 } else if [
1037 AES_CCM_16_64_128,
1038 AES_CCM_16_64_256,
1039 AES_CCM_16_128_256,
1040 AES_CCM_16_128_256,
1041 ]
1042 .contains(alg)
1043 {
1044 Ok(13)
1045 } else if [
1046 AES_CCM_64_64_128,
1047 AES_CCM_64_64_256,
1048 AES_CCM_64_128_256,
1049 AES_CCM_64_128_256,
1050 ]
1051 .contains(alg)
1052 {
1053 Ok(7)
1054 } else {
1055 Err(CoseError::InvalidAlg())
1056 }
1057}
1058
1059pub(crate) fn gen_iv(
1060 partial_iv: &Vec<u8>,
1061 base_iv: &Vec<u8>,
1062 alg: &i32,
1063) -> CoseResultWithRet<Vec<u8>> {
1064 let size = get_iv_size(alg)?;
1065 let mut pv = partial_iv.clone();
1066 let mut padded = vec![0; size - pv.len()];
1067 padded.append(&mut pv);
1068 let mut iv = Vec::new();
1069 for i in 0..padded.len() {
1070 if i < base_iv.len() {
1071 iv.push(padded[i] ^ base_iv[i]);
1072 } else {
1073 iv.push(padded[i]);
1074 }
1075 }
1076 Ok(iv)
1077}