blob: 0fc78a158017d1f0847b5ab75eb19f195edfc6d9 [file] [log] [blame]
Alice Wang000595b2023-10-02 13:46:45 +00001// Copyright 2023, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Alice Wang7468ae42023-11-30 10:20:36 +000015use bssl_avf::{sha256, ApiName, Digester, EcKey, EcdsaError, Error, PKey, Result};
Alice Wang9bd98092023-11-10 14:08:12 +000016use coset::CborSerializable;
Alice Wang600ea5b2023-11-17 15:12:16 +000017use spki::{
Andrew Walbran5b879eb2023-12-18 13:49:02 +000018 der::{AnyRef, Decode, Encode},
19 AlgorithmIdentifier, ObjectIdentifier, SubjectPublicKeyInfoRef,
Alice Wang600ea5b2023-11-17 15:12:16 +000020};
21
22/// OID value for general-use NIST EC keys held in PKCS#8 and X.509; see RFC 5480 s2.1.1.
23const X509_NIST_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.2.1");
24
25/// OID value in `AlgorithmIdentifier.parameters` for P-256; see RFC 5480 s2.1.1.1.
26const ALGO_PARAM_P256_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7");
Alice Wang000595b2023-10-02 13:46:45 +000027
Alice Wang0271ee02023-11-15 15:03:42 +000028const MESSAGE1: &[u8] = b"test message 1";
29const MESSAGE2: &[u8] = b"test message 2";
30
Alice Wang000595b2023-10-02 13:46:45 +000031#[test]
32fn ec_private_key_serialization() -> Result<()> {
Alice Wang9bd98092023-11-10 14:08:12 +000033 let mut ec_key = EcKey::new_p256()?;
34 ec_key.generate_key()?;
Alice Wang000595b2023-10-02 13:46:45 +000035 let der_encoded_ec_private_key = ec_key.ec_private_key()?;
36 let deserialized_ec_key = EcKey::from_ec_private_key(der_encoded_ec_private_key.as_slice())?;
37
38 assert_eq!(ec_key.cose_public_key()?, deserialized_ec_key.cose_public_key()?);
39 Ok(())
40}
Alice Wang9bd98092023-11-10 14:08:12 +000041
42#[test]
Alice Wang600ea5b2023-11-17 15:12:16 +000043fn subject_public_key_info_serialization() -> Result<()> {
44 let mut ec_key = EcKey::new_p256()?;
45 ec_key.generate_key()?;
Alice Wangeb77f7d2023-12-01 09:13:58 +000046 let pkey: PKey = ec_key.try_into()?;
Alice Wang600ea5b2023-11-17 15:12:16 +000047 let subject_public_key_info = pkey.subject_public_key_info()?;
48
Andrew Walbran5b879eb2023-12-18 13:49:02 +000049 let subject_public_key_info =
50 SubjectPublicKeyInfoRef::from_der(&subject_public_key_info).unwrap();
Alice Wang600ea5b2023-11-17 15:12:16 +000051 let expected_algorithm = AlgorithmIdentifier {
52 oid: X509_NIST_OID,
53 parameters: Some(AnyRef::from(&ALGO_PARAM_P256_OID)),
54 };
55 assert_eq!(expected_algorithm, subject_public_key_info.algorithm);
Andrew Walbran5b879eb2023-12-18 13:49:02 +000056 assert!(!subject_public_key_info.subject_public_key.to_der().unwrap().is_empty());
Alice Wang600ea5b2023-11-17 15:12:16 +000057 Ok(())
58}
59
60#[test]
Alice Wang306c8e22023-11-29 12:40:43 +000061fn p256_cose_public_key_serialization() -> Result<()> {
Alice Wang9bd98092023-11-10 14:08:12 +000062 let mut ec_key = EcKey::new_p256()?;
Alice Wang306c8e22023-11-29 12:40:43 +000063 check_cose_public_key_serialization(&mut ec_key)
64}
65
66#[test]
67fn p384_cose_public_key_serialization() -> Result<()> {
68 let mut ec_key = EcKey::new_p384()?;
69 check_cose_public_key_serialization(&mut ec_key)
70}
71
72fn check_cose_public_key_serialization(ec_key: &mut EcKey) -> Result<()> {
Alice Wang9bd98092023-11-10 14:08:12 +000073 ec_key.generate_key()?;
74 let cose_key = ec_key.cose_public_key()?;
75 let cose_key_data = cose_key.clone().to_vec().unwrap();
Alice Wangbe7a4b12023-12-01 11:53:36 +000076 let deserialized_ec_key = EcKey::from_cose_public_key_slice(&cose_key_data)?;
Alice Wang9bd98092023-11-10 14:08:12 +000077
78 assert_eq!(cose_key, deserialized_ec_key.cose_public_key()?);
79 Ok(())
80}
Alice Wang0271ee02023-11-15 15:03:42 +000081
82#[test]
83fn ecdsa_p256_signing_and_verification_succeed() -> Result<()> {
84 let mut ec_key = EcKey::new_p256()?;
85 ec_key.generate_key()?;
Alice Wang884648d2023-12-01 09:50:20 +000086 let digester = Digester::sha256();
87 let digest = digester.digest(MESSAGE1)?;
88 assert_eq!(digest, sha256(MESSAGE1)?);
Alice Wang0271ee02023-11-15 15:03:42 +000089
Alan Stokes20b5ab22024-05-10 15:40:43 +010090 let signature = ec_key.ecdsa_sign_der(&digest)?;
Alan Stokesb2f52fb2024-05-09 10:12:55 +010091 ec_key.ecdsa_verify_der(&signature, &digest)?;
Alice Wangbe7a4b12023-12-01 11:53:36 +000092 // Building a `PKey` from a temporary `CoseKey` should work as the lifetime
93 // of the `PKey` is not tied to the lifetime of the `CoseKey`.
94 let pkey = PKey::from_cose_public_key(&ec_key.cose_public_key()?)?;
Alice Wang884648d2023-12-01 09:50:20 +000095 pkey.verify(&signature, MESSAGE1, Some(digester))
96}
97
98#[test]
99fn ecdsa_p384_signing_and_verification_succeed() -> Result<()> {
100 let mut ec_key = EcKey::new_p384()?;
101 ec_key.generate_key()?;
102 let digester = Digester::sha384();
103 let digest = digester.digest(MESSAGE1)?;
104
Alan Stokes20b5ab22024-05-10 15:40:43 +0100105 let signature = ec_key.ecdsa_sign_der(&digest)?;
Alan Stokesb2f52fb2024-05-09 10:12:55 +0100106 ec_key.ecdsa_verify_der(&signature, &digest)?;
Alice Wangbe7a4b12023-12-01 11:53:36 +0000107 let pkey = PKey::from_cose_public_key(&ec_key.cose_public_key()?)?;
Alice Wang884648d2023-12-01 09:50:20 +0000108 pkey.verify(&signature, MESSAGE1, Some(digester))
Alice Wang0271ee02023-11-15 15:03:42 +0000109}
110
111#[test]
112fn verifying_ecdsa_p256_signed_with_a_different_key_fails() -> Result<()> {
113 let mut ec_key1 = EcKey::new_p256()?;
114 ec_key1.generate_key()?;
115 let digest = sha256(MESSAGE1)?;
Alan Stokes20b5ab22024-05-10 15:40:43 +0100116 let signature = ec_key1.ecdsa_sign_der(&digest)?;
Alice Wang0271ee02023-11-15 15:03:42 +0000117
118 let mut ec_key2 = EcKey::new_p256()?;
119 ec_key2.generate_key()?;
Alan Stokesb2f52fb2024-05-09 10:12:55 +0100120 let err = ec_key2.ecdsa_verify_der(&signature, &digest).unwrap_err();
Alice Wang0271ee02023-11-15 15:03:42 +0000121 let expected_err = Error::CallFailed(ApiName::ECDSA_verify, EcdsaError::BadSignature.into());
122 assert_eq!(expected_err, err);
Alice Wang7468ae42023-11-30 10:20:36 +0000123
124 let pkey: PKey = ec_key2.try_into()?;
125 let err = pkey.verify(&signature, MESSAGE1, Some(Digester::sha256())).unwrap_err();
126 let expected_err =
127 Error::CallFailed(ApiName::EVP_DigestVerify, EcdsaError::BadSignature.into());
128 assert_eq!(expected_err, err);
Alice Wang0271ee02023-11-15 15:03:42 +0000129 Ok(())
130}
131
132#[test]
133fn verifying_ecdsa_p256_signed_with_a_different_message_fails() -> Result<()> {
134 let mut ec_key = EcKey::new_p256()?;
135 ec_key.generate_key()?;
136 let digest1 = sha256(MESSAGE1)?;
Alan Stokes20b5ab22024-05-10 15:40:43 +0100137 let signature = ec_key.ecdsa_sign_der(&digest1)?;
Alice Wang0271ee02023-11-15 15:03:42 +0000138 let digest2 = sha256(MESSAGE2)?;
139
Alan Stokesb2f52fb2024-05-09 10:12:55 +0100140 let err = ec_key.ecdsa_verify_der(&signature, &digest2).unwrap_err();
Alice Wang0271ee02023-11-15 15:03:42 +0000141 let expected_err = Error::CallFailed(ApiName::ECDSA_verify, EcdsaError::BadSignature.into());
142 assert_eq!(expected_err, err);
143 Ok(())
144}
Alan Stokes20b5ab22024-05-10 15:40:43 +0100145
146#[test]
147fn ecdsa_cose_signing_and_verification_succeed() -> Result<()> {
148 let digest = sha256(MESSAGE1)?;
149 let mut ec_key = EcKey::new_p256()?;
150 ec_key.generate_key()?;
151
152 let signature = ec_key.ecdsa_sign_cose(&digest)?;
153 ec_key.ecdsa_verify_cose(&signature, &digest)?;
154 assert_eq!(signature.len(), 64);
155 Ok(())
156}
157
158#[test]
159fn verifying_ecdsa_cose_signed_with_a_different_message_fails() -> Result<()> {
160 let digest = sha256(MESSAGE1)?;
161 let mut ec_key = EcKey::new_p256()?;
162 ec_key.generate_key()?;
163
164 let signature = ec_key.ecdsa_sign_cose(&digest)?;
165
166 let err = ec_key.ecdsa_verify_cose(&signature, &sha256(MESSAGE2)?).unwrap_err();
167 let expected_err = Error::CallFailed(ApiName::ECDSA_verify, EcdsaError::BadSignature.into());
168 assert_eq!(expected_err, err);
169 Ok(())
170}
171
172#[test]
173fn verifying_ecdsa_cose_signed_as_der_fails() -> Result<()> {
174 let digest = sha256(MESSAGE1)?;
175 let mut ec_key = EcKey::new_p256()?;
176 ec_key.generate_key()?;
177
178 let signature = ec_key.ecdsa_sign_cose(&digest)?;
179 let err = ec_key.ecdsa_verify_der(&signature, &digest).unwrap_err();
180 let expected_err = Error::CallFailed(ApiName::ECDSA_verify, EcdsaError::BadSignature.into());
181 assert_eq!(expected_err, err);
182 Ok(())
183}