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 : 74 : // Default to avoid nullptr on getter and cleanly handle new products/clients before 75 : // they provide their own. 76 : UnimplementedDACVerifier gDefaultDACVerifier; 77 : 78 : DeviceAttestationVerifier * gDacVerifier = &gDefaultDACVerifier; 79 : 80 : } // namespace 81 : 82 93 : CHIP_ERROR DeviceAttestationVerifier::ValidateAttestationSignature(const P256PublicKey & pubkey, 83 : const ByteSpan & attestationElements, 84 : const ByteSpan & attestationChallenge, 85 : const P256ECDSASignature & signature) 86 : { 87 93 : Hash_SHA256_stream hashStream; 88 : uint8_t md[kSHA256_Hash_Length]; 89 93 : MutableByteSpan messageDigestSpan(md); 90 : 91 93 : ReturnErrorOnFailure(hashStream.Begin()); 92 93 : ReturnErrorOnFailure(hashStream.AddData(attestationElements)); 93 93 : ReturnErrorOnFailure(hashStream.AddData(attestationChallenge)); 94 93 : ReturnErrorOnFailure(hashStream.Finish(messageDigestSpan)); 95 : 96 93 : ReturnErrorOnFailure(pubkey.ECDSA_validate_hash_signature(messageDigestSpan.data(), messageDigestSpan.size(), signature)); 97 : 98 92 : return CHIP_NO_ERROR; 99 93 : } 100 : 101 3 : DeviceAttestationVerifier * GetDeviceAttestationVerifier() 102 : { 103 3 : return gDacVerifier; 104 : } 105 : 106 2 : void SetDeviceAttestationVerifier(DeviceAttestationVerifier * verifier) 107 : { 108 2 : if (verifier == nullptr) 109 : { 110 0 : return; 111 : } 112 : 113 2 : gDacVerifier = verifier; 114 : } 115 : 116 0 : static inline Platform::ScopedMemoryBufferWithSize<uint8_t> CopyByteSpanHelper(const ByteSpan & span_to_copy) 117 : { 118 0 : Platform::ScopedMemoryBufferWithSize<uint8_t> bufferCopy; 119 0 : if (bufferCopy.Alloc(span_to_copy.size())) 120 : { 121 0 : memcpy(bufferCopy.Get(), span_to_copy.data(), span_to_copy.size()); 122 : } 123 0 : return bufferCopy; 124 : } 125 : 126 0 : DeviceAttestationVerifier::AttestationDeviceInfo::AttestationDeviceInfo(const AttestationInfo & attestationInfo) : 127 0 : mPaiDerBuffer(CopyByteSpanHelper(attestationInfo.paiDerBuffer)), 128 0 : mDacDerBuffer(CopyByteSpanHelper(attestationInfo.dacDerBuffer)), mBasicInformationVendorId(attestationInfo.vendorId), 129 0 : mBasicInformationProductId(attestationInfo.productId) 130 : { 131 0 : ByteSpan certificationDeclarationSpan; 132 0 : ByteSpan attestationNonceSpan; 133 : uint32_t timestampDeconstructed; 134 0 : ByteSpan firmwareInfoSpan; 135 0 : DeviceAttestationVendorReservedDeconstructor vendorReserved; 136 : 137 0 : if (DeconstructAttestationElements(attestationInfo.attestationElementsBuffer, certificationDeclarationSpan, 138 : attestationNonceSpan, timestampDeconstructed, firmwareInfoSpan, 139 0 : vendorReserved) == CHIP_NO_ERROR) 140 : { 141 0 : mCdBuffer = CopyByteSpanHelper(certificationDeclarationSpan); 142 : } 143 0 : } 144 : 145 : } // namespace Credentials 146 : } // namespace chip