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