Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021 Project CHIP Authors
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 : #include "DeviceAttestationVerifier.h"
18 :
19 : #include <credentials/DeviceAttestationConstructor.h>
20 : #include <crypto/CHIPCryptoPAL.h>
21 : #include <lib/support/CHIPMem.h>
22 :
23 : using namespace chip::Crypto;
24 :
25 : namespace chip {
26 : namespace Credentials {
27 :
28 : namespace {
29 :
30 : // Version to have a default placeholder so the getter never
31 : // returns `nullptr` by default.
32 : class UnimplementedDACVerifier : public DeviceAttestationVerifier
33 : {
34 : public:
35 0 : void VerifyAttestationInformation(const AttestationInfo & info,
36 : Callback::Callback<OnAttestationInformationVerification> * onCompletion) override
37 : {
38 : (void) info;
39 : (void) onCompletion;
40 0 : }
41 :
42 1 : AttestationVerificationResult ValidateCertificationDeclarationSignature(const ByteSpan & cmsEnvelopeBuffer,
43 : ByteSpan & certDeclBuffer) override
44 : {
45 : (void) cmsEnvelopeBuffer;
46 : (void) certDeclBuffer;
47 1 : return AttestationVerificationResult::kNotImplemented;
48 : }
49 :
50 0 : AttestationVerificationResult ValidateCertificateDeclarationPayload(const ByteSpan & certDeclBuffer,
51 : const ByteSpan & firmwareInfo,
52 : const DeviceInfoForAttestation & deviceInfo) override
53 : {
54 : (void) certDeclBuffer;
55 : (void) firmwareInfo;
56 : (void) deviceInfo;
57 0 : return AttestationVerificationResult::kNotImplemented;
58 : }
59 :
60 0 : CHIP_ERROR VerifyNodeOperationalCSRInformation(const ByteSpan & nocsrElementsBuffer,
61 : const ByteSpan & attestationChallengeBuffer,
62 : const ByteSpan & attestationSignatureBuffer,
63 : const Crypto::P256PublicKey & dacPublicKey, const ByteSpan & csrNonce) override
64 : {
65 : (void) nocsrElementsBuffer;
66 : (void) attestationChallengeBuffer;
67 : (void) attestationSignatureBuffer;
68 : (void) dacPublicKey;
69 : (void) csrNonce;
70 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
71 : }
72 :
73 0 : void CheckForRevokedDACChain(const AttestationInfo & info,
74 : Callback::Callback<OnAttestationInformationVerification> * onCompletion) override
75 : {
76 : (void) info;
77 : (void) onCompletion;
78 0 : VerifyOrDie(false);
79 : }
80 : };
81 :
82 : // Default to avoid nullptr on getter and cleanly handle new products/clients before
83 : // they provide their own.
84 : UnimplementedDACVerifier gDefaultDACVerifier;
85 :
86 : DeviceAttestationVerifier * gDacVerifier = &gDefaultDACVerifier;
87 :
88 : } // namespace
89 :
90 95 : CHIP_ERROR DeviceAttestationVerifier::ValidateAttestationSignature(const P256PublicKey & pubkey,
91 : const ByteSpan & attestationElements,
92 : const ByteSpan & attestationChallenge,
93 : const P256ECDSASignature & signature)
94 : {
95 95 : Hash_SHA256_stream hashStream;
96 : uint8_t md[kSHA256_Hash_Length];
97 95 : MutableByteSpan messageDigestSpan(md);
98 :
99 95 : ReturnErrorOnFailure(hashStream.Begin());
100 95 : ReturnErrorOnFailure(hashStream.AddData(attestationElements));
101 95 : ReturnErrorOnFailure(hashStream.AddData(attestationChallenge));
102 95 : ReturnErrorOnFailure(hashStream.Finish(messageDigestSpan));
103 :
104 95 : ReturnErrorOnFailure(pubkey.ECDSA_validate_hash_signature(messageDigestSpan.data(), messageDigestSpan.size(), signature));
105 :
106 94 : return CHIP_NO_ERROR;
107 95 : }
108 :
109 3 : DeviceAttestationVerifier * GetDeviceAttestationVerifier()
110 : {
111 3 : return gDacVerifier;
112 : }
113 :
114 2 : void SetDeviceAttestationVerifier(DeviceAttestationVerifier * verifier)
115 : {
116 2 : if (verifier == nullptr)
117 : {
118 0 : return;
119 : }
120 :
121 2 : gDacVerifier = verifier;
122 : }
123 :
124 0 : static inline Platform::ScopedMemoryBufferWithSize<uint8_t> CopyByteSpanHelper(const ByteSpan & span_to_copy)
125 : {
126 0 : Platform::ScopedMemoryBufferWithSize<uint8_t> bufferCopy;
127 0 : if (bufferCopy.Alloc(span_to_copy.size()))
128 : {
129 0 : memcpy(bufferCopy.Get(), span_to_copy.data(), span_to_copy.size());
130 : }
131 0 : return bufferCopy;
132 : }
133 :
134 0 : DeviceAttestationVerifier::AttestationDeviceInfo::AttestationDeviceInfo(const AttestationInfo & attestationInfo) :
135 0 : mPaiDerBuffer(CopyByteSpanHelper(attestationInfo.paiDerBuffer)),
136 0 : mDacDerBuffer(CopyByteSpanHelper(attestationInfo.dacDerBuffer)), mBasicInformationVendorId(attestationInfo.vendorId),
137 0 : mBasicInformationProductId(attestationInfo.productId)
138 : {
139 0 : ByteSpan certificationDeclarationSpan;
140 0 : ByteSpan attestationNonceSpan;
141 : uint32_t timestampDeconstructed;
142 0 : ByteSpan firmwareInfoSpan;
143 0 : DeviceAttestationVendorReservedDeconstructor vendorReserved;
144 :
145 0 : if (DeconstructAttestationElements(attestationInfo.attestationElementsBuffer, certificationDeclarationSpan,
146 : attestationNonceSpan, timestampDeconstructed, firmwareInfoSpan,
147 0 : vendorReserved) == CHIP_NO_ERROR)
148 : {
149 0 : mCdBuffer = CopyByteSpanHelper(certificationDeclarationSpan);
150 : }
151 0 : }
152 :
153 : } // namespace Credentials
154 : } // namespace chip
|