Line data Source code
1 : /*
2 : * Copyright (c) 2023 Project CHIP Authors
3 : * All rights reserved.
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 :
18 : #include <crypto/RawKeySessionKeystore.h>
19 :
20 : #include <lib/support/BufferReader.h>
21 :
22 : #include <cstdint>
23 :
24 : namespace chip {
25 : namespace Crypto {
26 :
27 : // The underlying representation of the HKDF key handle
28 : struct RawHkdfKeyHandle
29 : {
30 26 : ByteSpan Span() const { return ByteSpan(data, size); }
31 :
32 : // Cap the data size so that the entire structure fits in the opaque context of the HKDF key handle.
33 : static constexpr size_t kMaxDataSize = std::min<size_t>(CHIP_CONFIG_HKDF_KEY_HANDLE_CONTEXT_SIZE - sizeof(uint8_t), UINT8_MAX);
34 :
35 : uint8_t data[kMaxDataSize];
36 : uint8_t size;
37 : };
38 :
39 204 : CHIP_ERROR RawKeySessionKeystore::CreateKey(const Symmetric128BitsKeyByteArray & keyMaterial, Aes128KeyHandle & key)
40 : {
41 204 : memcpy(key.AsMutable<Symmetric128BitsKeyByteArray>(), keyMaterial, sizeof(Symmetric128BitsKeyByteArray));
42 204 : return CHIP_NO_ERROR;
43 : }
44 :
45 39 : CHIP_ERROR RawKeySessionKeystore::CreateKey(const Symmetric128BitsKeyByteArray & keyMaterial, Hmac128KeyHandle & key)
46 : {
47 39 : memcpy(key.AsMutable<Symmetric128BitsKeyByteArray>(), keyMaterial, sizeof(Symmetric128BitsKeyByteArray));
48 39 : return CHIP_NO_ERROR;
49 : }
50 :
51 22 : CHIP_ERROR RawKeySessionKeystore::CreateKey(const ByteSpan & keyMaterial, HkdfKeyHandle & key)
52 : {
53 22 : RawHkdfKeyHandle & rawKey = key.AsMutable<RawHkdfKeyHandle>();
54 :
55 22 : VerifyOrReturnError(keyMaterial.size() <= sizeof(rawKey.data), CHIP_ERROR_BUFFER_TOO_SMALL);
56 22 : memcpy(rawKey.data, keyMaterial.data(), keyMaterial.size());
57 22 : rawKey.size = static_cast<uint8_t>(keyMaterial.size());
58 :
59 22 : return CHIP_NO_ERROR;
60 : }
61 :
62 37 : CHIP_ERROR RawKeySessionKeystore::DeriveKey(const P256ECDHDerivedSecret & secret, const ByteSpan & salt, const ByteSpan & info,
63 : Aes128KeyHandle & key)
64 : {
65 37 : HKDF_sha hkdf;
66 :
67 37 : return hkdf.HKDF_SHA256(secret.ConstBytes(), secret.Length(), salt.data(), salt.size(), info.data(), info.size(),
68 74 : key.AsMutable<Symmetric128BitsKeyByteArray>(), sizeof(Symmetric128BitsKeyByteArray));
69 37 : }
70 :
71 1334 : CHIP_ERROR RawKeySessionKeystore::DeriveSessionKeys(const ByteSpan & secret, const ByteSpan & salt, const ByteSpan & info,
72 : Aes128KeyHandle & i2rKey, Aes128KeyHandle & r2iKey,
73 : AttestationChallenge & attestationChallenge)
74 : {
75 1334 : HKDF_sha hkdf;
76 : uint8_t keyMaterial[2 * sizeof(Symmetric128BitsKeyByteArray) + AttestationChallenge::Capacity()];
77 :
78 1334 : ReturnErrorOnFailure(hkdf.HKDF_SHA256(secret.data(), secret.size(), salt.data(), salt.size(), info.data(), info.size(),
79 : keyMaterial, sizeof(keyMaterial)));
80 :
81 1334 : Encoding::LittleEndian::Reader reader(keyMaterial, sizeof(keyMaterial));
82 :
83 1334 : return reader.ReadBytes(i2rKey.AsMutable<Symmetric128BitsKeyByteArray>(), sizeof(Symmetric128BitsKeyByteArray))
84 1334 : .ReadBytes(r2iKey.AsMutable<Symmetric128BitsKeyByteArray>(), sizeof(Symmetric128BitsKeyByteArray))
85 1334 : .ReadBytes(attestationChallenge.Bytes(), AttestationChallenge::Capacity())
86 1334 : .StatusCode();
87 1334 : }
88 :
89 26 : CHIP_ERROR RawKeySessionKeystore::DeriveSessionKeys(const HkdfKeyHandle & hkdfKey, const ByteSpan & salt, const ByteSpan & info,
90 : Aes128KeyHandle & i2rKey, Aes128KeyHandle & r2iKey,
91 : AttestationChallenge & attestationChallenge)
92 : {
93 26 : return DeriveSessionKeys(hkdfKey.As<RawHkdfKeyHandle>().Span(), salt, info, i2rKey, r2iKey, attestationChallenge);
94 : }
95 :
96 2960 : void RawKeySessionKeystore::DestroyKey(Symmetric128BitsKeyHandle & key)
97 : {
98 2960 : ClearSecretData(key.AsMutable<Symmetric128BitsKeyByteArray>());
99 2960 : }
100 :
101 22 : void RawKeySessionKeystore::DestroyKey(HkdfKeyHandle & key)
102 : {
103 22 : RawHkdfKeyHandle & rawKey = key.AsMutable<RawHkdfKeyHandle>();
104 :
105 22 : ClearSecretData(rawKey.data);
106 22 : rawKey.size = 0;
107 22 : }
108 :
109 : } // namespace Crypto
110 : } // namespace chip
|