Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021-2022 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 :
18 : /**
19 : * @brief Defines a table of fabrics that have provisioned the device.
20 : */
21 :
22 : #pragma once
23 :
24 : #include <lib/core/CHIPPersistentStorageDelegate.h>
25 : #include <lib/core/Optional.h>
26 : #include <lib/core/TLV.h>
27 : #include <system/SystemClock.h>
28 :
29 : namespace chip {
30 :
31 : class LastKnownGoodTime
32 : {
33 : public:
34 0 : LastKnownGoodTime() {}
35 :
36 : /**
37 : * Initialize Last Known Good Time to the later of firmware build time or
38 : * last known good time persisted in storage. Persist the selected value
39 : * if this differs from the value in storage or no value is yet persisted.
40 : *
41 : * @param storage storage delegate to persist Last Known Good Time
42 : * @return CHIP_NO_ERROR on success, else an appropriate CHIP_ERROR
43 : */
44 : CHIP_ERROR Init(PersistentStorageDelegate * storage);
45 :
46 : /**
47 : * Get the current Last Known Good Time.
48 : *
49 : * @param lastKnownGoodChipEpochTime (out) the current last known good time, if any is known
50 : * &return CHIP_NO_ERROR on success, else an appropriate CHIP_ERROR
51 : */
52 0 : CHIP_ERROR GetLastKnownGoodChipEpochTime(System::Clock::Seconds32 & lastKnownGoodChipEpochTime) const
53 : {
54 0 : VerifyOrReturnError(mLastKnownGoodChipEpochTime.HasValue(), CHIP_ERROR_INCORRECT_STATE);
55 0 : lastKnownGoodChipEpochTime = mLastKnownGoodChipEpochTime.Value();
56 0 : return CHIP_NO_ERROR;
57 : }
58 :
59 : /**
60 : * Validate that the passed Last Known Good Time is within bounds and then
61 : * store this and write back to storage. Legal values are those which are
62 : * not earlier than firmware build time or any of our stored certificates'
63 : * NotBefore times:
64 : *
65 : * 3.5.6.1. Last Known Good UTC Time
66 : *
67 : * A Node MAY adjust the Last Known Good UTC Time backwards if it
68 : * believes the current Last Known Good UTC Time is incorrect and it has
69 : * a good time value from a trusted source. The Node SHOULD NOT adjust
70 : * the Last Known Good UTC to a time before the later of:
71 : * • The build timestamp of its currently running software image
72 : * • The not-before timestamp of any of its operational certificates
73 : *
74 : * @param lastKnownGoodChipEpochTime Last Known Good Time in seconds since CHIP epoch
75 : * @param notBefore the latest NotBefore time of all installed certificates
76 : * @return CHIP_NO_ERROR on success, else an appopriate CHIP_ERROR
77 : */
78 : CHIP_ERROR SetLastKnownGoodChipEpochTime(System::Clock::Seconds32 lastKnownGoodChipEpochTime,
79 : System::Clock::Seconds32 notBefore);
80 :
81 : /**
82 : * Update the Last Known Good Time to the later of the current value and
83 : * the passed value and store in RAM. This does not persist the value.
84 : * Persist only happens if CommitPendingLastKnownGoodChipEpochTime is
85 : * called.
86 : *
87 : * @param lastKnownGoodChipEpochTime Last Known Good Time in seconds since CHIP epoch
88 : * @return CHIP_NO_ERROR on success, else an appopriate CHIP_ERROR
89 : */
90 : CHIP_ERROR UpdatePendingLastKnownGoodChipEpochTime(System::Clock::Seconds32 lastKnownGoodChipEpochTime);
91 :
92 : /*
93 : * Commit the pending Last Known Good Time in RAM to storage.
94 : *
95 : * @return CHIP_NO_ERROR on success, else an appopriate CHIP_ERROR
96 : */
97 : CHIP_ERROR CommitPendingLastKnownGoodChipEpochTime();
98 :
99 : /*
100 : * Revert the Last Known Good Time to the fail-safe backup value in
101 : * persistence if any exists.
102 : *
103 : * @return CHIP_NO_ERROR on success, else an appopriate CHIP_ERROR
104 : */
105 : CHIP_ERROR RevertPendingLastKnownGoodChipEpochTime();
106 :
107 : private:
108 : static constexpr size_t LastKnownGoodTimeTLVMaxSize()
109 : {
110 : // We have Last Known Good Time and, optionally, a previous Last known
111 : // good time for fail safe cleanup.
112 : return TLV::EstimateStructOverhead(sizeof(uint32_t), sizeof(uint32_t));
113 : }
114 :
115 : /**
116 : * Log the message, appending the passed CHIP epoch time in ISO8601 format.
117 : *
118 : * @param msg message to log with ISO8601 time appended
119 : * @param chipEpochTime time in seconds from the CHIP epoch
120 : */
121 : void LogTime(const char * msg, System::Clock::Seconds32 chipEpochTime);
122 :
123 : /**
124 : * Load the Last Known Good Time from storage.
125 : *
126 : * @param lastKnownGoodChipEpochTime (out) Last Known Good Time as seconds from CHIP epoch
127 : * @return CHIP_NO_ERROR on success, else an appropriate CHIP_ERROR
128 : */
129 : CHIP_ERROR LoadLastKnownGoodChipEpochTime(System::Clock::Seconds32 & lastKnownGoodChipEpochTime) const;
130 :
131 : /**
132 : * Store the Last Known Good Time to storage.
133 : *
134 : * @param lastKnownGoodChipEpochTime Last Known Good Time as seconds from CHIP epoch
135 : * @return CHIP_NO_ERROR on success, else an appropriate CHIP_ERROR
136 : */
137 : CHIP_ERROR StoreLastKnownGoodChipEpochTime(System::Clock::Seconds32 lastKnownGoodChipEpochTime) const;
138 :
139 : PersistentStorageDelegate * mStorage = nullptr;
140 : Optional<System::Clock::Seconds32> mLastKnownGoodChipEpochTime;
141 : };
142 :
143 : } // namespace chip
|