Matter SDK Coverage Report
Current view: top level - lib/core - CHIPKeyIds.cpp (source / functions) Coverage Total Hit
Test: SHA:14e806bf827a16a4c404c46ad3389250a52fb209 Lines: 98.3 % 116 114
Test Date: 2026-02-03 08:12:34 Functions: 100.0 % 14 14

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020-2021 Project CHIP Authors
       4              :  *    Copyright (c) 2016-2017 Nest Labs, Inc.
       5              :  *
       6              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7              :  *    you may not use this file except in compliance with the License.
       8              :  *    You may obtain a copy of the License at
       9              :  *
      10              :  *        http://www.apache.org/licenses/LICENSE-2.0
      11              :  *
      12              :  *    Unless required by applicable law or agreed to in writing, software
      13              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15              :  *    See the License for the specific language governing permissions and
      16              :  *    limitations under the License.
      17              :  */
      18              : #include <lib/core/CHIPKeyIds.h>
      19              : 
      20              : #include <lib/support/CodeUtils.h>
      21              : 
      22              : namespace chip {
      23              : 
      24              : /**
      25              :  *  Determine whether the specified key ID belongs to one of the application
      26              :  *  group key types (static or rotating).
      27              :  *
      28              :  *  @param[in]   keyId     CHIP key identifier.
      29              :  *  @return      true      if the keyId is of rotating or static key type.
      30              :  *
      31              :  */
      32            5 : bool ChipKeyId::IsAppGroupKey(uint32_t keyId)
      33              : {
      34            5 :     return IsAppStaticKey(keyId) || IsAppRotatingKey(keyId);
      35              : }
      36              : 
      37              : /**
      38              :  *  Determine whether the specified application group key ID uses "current" epoch key.
      39              :  *
      40              :  *  @param[in]   keyId     CHIP application group key identifier.
      41              :  *  @return      true      if the keyId indicates usage of the current epoch key.
      42              :  *
      43              :  */
      44           16 : bool ChipKeyId::UsesCurrentEpochKey(uint32_t keyId)
      45              : {
      46           16 :     return IncorporatesEpochKey(keyId) && ((keyId & kFlag_UseCurrentEpochKey) != 0);
      47              : }
      48              : 
      49              : /**
      50              :  *  Determine whether the specified application group key ID incorporates root key.
      51              :  *
      52              :  *  @param[in]   keyId     CHIP application group key identifier.
      53              :  *  @return      true      if the keyId incorporates root key.
      54              :  *
      55              :  */
      56           12 : bool ChipKeyId::IncorporatesRootKey(uint32_t keyId)
      57              : {
      58           12 :     uint32_t keyType = GetType(keyId);
      59           12 :     return keyType == kType_AppStaticKey || keyType == kType_AppRotatingKey || keyType == kType_AppRootKey ||
      60           12 :         keyType == kType_AppIntermediateKey;
      61              : }
      62              : 
      63              : /**
      64              :  *  Determine whether the specified application group key ID incorporates group master key.
      65              :  *
      66              :  *  @param[in]   keyId     CHIP application group key identifier.
      67              :  *  @return      true      if the keyId incorporates group master key.
      68              :  *
      69              :  */
      70            4 : bool ChipKeyId::IncorporatesAppGroupMasterKey(uint32_t keyId)
      71              : {
      72            4 :     uint32_t keyType = GetType(keyId);
      73            4 :     return keyType == kType_AppStaticKey || keyType == kType_AppRotatingKey || keyType == kType_AppGroupMasterKey;
      74              : }
      75              : 
      76              : /**
      77              :  *  Construct application group key ID given constituent key IDs and other information.
      78              :  *
      79              :  *  @param[in]   keyType               Derived application group key type.
      80              :  *  @param[in]   rootKeyId             Root key ID used to derive application group key.
      81              :  *  @param[in]   epochKeyId            Epoch key ID used to derive application group key.
      82              :  *  @param[in]   appGroupMasterKeyId   Application group master key ID used to derive
      83              :  *                                     application group key.
      84              :  *  @param[in]   useCurrentEpochKey    A boolean flag that indicates if key should be derived
      85              :  *                                     using "current" epoch key.
      86              :  *  @return      application group key ID.
      87              :  *
      88              :  */
      89            5 : uint32_t ChipKeyId::MakeAppKeyId(uint32_t keyType, uint32_t rootKeyId, uint32_t epochKeyId, uint32_t appGroupMasterKeyId,
      90              :                                  bool useCurrentEpochKey)
      91              : {
      92            5 :     return (keyType | (rootKeyId & kMask_RootKeyNumber) | (appGroupMasterKeyId & kMask_GroupLocalNumber) |
      93            5 :             (useCurrentEpochKey ? static_cast<uint32_t>(kFlag_UseCurrentEpochKey) : (epochKeyId & kMask_EpochKeyNumber)));
      94              : }
      95              : 
      96              : /**
      97              :  *  Construct application intermediate key ID given constituent key IDs.
      98              :  *
      99              :  *  @param[in]   rootKeyId             Root key ID used to derive application intermediate key.
     100              :  *  @param[in]   epochKeyId            Epoch key ID used to derive application intermediate key.
     101              :  *  @param[in]   useCurrentEpochKey    A boolean flag that indicates if key should be derived
     102              :  *                                     using "current" epoch key.
     103              :  *  @return      application intermediate key ID.
     104              :  *
     105              :  */
     106            1 : uint32_t ChipKeyId::MakeAppIntermediateKeyId(uint32_t rootKeyId, uint32_t epochKeyId, bool useCurrentEpochKey)
     107              : {
     108            1 :     return MakeAppKeyId(kType_AppIntermediateKey, rootKeyId, epochKeyId, kNone, useCurrentEpochKey);
     109              : }
     110              : 
     111              : /**
     112              :  *  Construct application rotating key ID given constituent key IDs and other information.
     113              :  *
     114              :  *  @param[in]   rootKeyId             Root key ID used to derive application rotating key.
     115              :  *  @param[in]   epochKeyId            Epoch key ID used to derive application rotating key.
     116              :  *  @param[in]   appGroupMasterKeyId   Application group master key ID used to derive
     117              :  *                                     application rotating key.
     118              :  *  @param[in]   useCurrentEpochKey    A boolean flag that indicates if key should be derived
     119              :  *                                     using "current" epoch key.
     120              :  *  @return      application rotating key ID.
     121              :  *
     122              :  */
     123            1 : uint32_t ChipKeyId::MakeAppRotatingKeyId(uint32_t rootKeyId, uint32_t epochKeyId, uint32_t appGroupMasterKeyId,
     124              :                                          bool useCurrentEpochKey)
     125              : {
     126            1 :     return MakeAppKeyId(kType_AppRotatingKey, rootKeyId, epochKeyId, appGroupMasterKeyId, useCurrentEpochKey);
     127              : }
     128              : 
     129              : /**
     130              :  *  Construct application static key ID given constituent key IDs.
     131              :  *
     132              :  *  @param[in]   rootKeyId             Root key ID used to derive application static key.
     133              :  *  @param[in]   appGroupMasterKeyId   Application group master key ID used to derive
     134              :  *                                     application static key.
     135              :  *  @return      application static key ID.
     136              :  *
     137              :  */
     138            2 : uint32_t ChipKeyId::MakeAppStaticKeyId(uint32_t rootKeyId, uint32_t appGroupMasterKeyId)
     139              : {
     140            2 :     return MakeAppKeyId(kType_AppStaticKey, rootKeyId, kNone, appGroupMasterKeyId, false);
     141              : }
     142              : 
     143              : /**
     144              :  *  Convert application key ID to application static key ID.
     145              :  *
     146              :  *  @param[in]   keyId                 Application key ID.
     147              :  *  @return      application static key ID.
     148              :  *
     149              :  */
     150            1 : uint32_t ChipKeyId::ConvertToStaticAppKeyId(uint32_t keyId)
     151              : {
     152            1 :     return MakeAppStaticKeyId(GetRootKeyId(keyId), GetAppGroupMasterKeyId(keyId));
     153              : }
     154              : 
     155              : /**
     156              :  *  Update application group key ID with new epoch key number.
     157              :  *
     158              :  *  @param[in]   keyId                 Application key ID.
     159              :  *  @param[in]   epochKeyId            Epoch key ID, which will be used in construction
     160              :  *                                     of the updated application key ID.
     161              :  *  @return      application key ID.
     162              :  *
     163              :  */
     164            1 : uint32_t ChipKeyId::UpdateEpochKeyId(uint32_t keyId, uint32_t epochKeyId)
     165              : {
     166            1 :     return (keyId & ~(kFlag_UseCurrentEpochKey | kMask_EpochKeyNumber)) | (epochKeyId & kMask_EpochKeyNumber);
     167              : }
     168              : 
     169              : /**
     170              :  *  Determine whether key identifier has valid (legal) value.
     171              :  *
     172              :  *  @param[in]   keyId                 CHIP key ID.
     173              :  *  @return      true                  if key ID value is valid.
     174              :  *
     175              :  */
     176            9 : bool ChipKeyId::IsValidKeyId(uint32_t keyId)
     177              : {
     178            9 :     unsigned int usedBits = kMask_KeyType;
     179              : 
     180            9 :     switch (GetType(keyId))
     181              :     {
     182            1 :     case kType_None:
     183            1 :         return false;
     184            1 :     case kType_General:
     185              :     case kType_Session:
     186            1 :         usedBits |= kMask_KeyNumber;
     187            1 :         break;
     188            1 :     case kType_AppStaticKey:
     189            1 :         usedBits |= kMask_RootKeyNumber | kMask_GroupLocalNumber;
     190            1 :         break;
     191            1 :     case kType_AppRotatingKey:
     192            1 :         usedBits |= kFlag_UseCurrentEpochKey | kMask_RootKeyNumber | kMask_GroupLocalNumber;
     193            1 :         if (!UsesCurrentEpochKey(keyId))
     194              :         {
     195            1 :             usedBits |= kMask_EpochKeyNumber;
     196              :         }
     197            1 :         break;
     198            1 :     case kType_AppRootKey:
     199            1 :         usedBits |= kMask_RootKeyNumber;
     200            1 :         break;
     201            1 :     case kType_AppIntermediateKey:
     202            1 :         usedBits |= kFlag_UseCurrentEpochKey | kMask_RootKeyNumber;
     203            1 :         if (!UsesCurrentEpochKey(keyId))
     204              :         {
     205            1 :             usedBits |= kMask_EpochKeyNumber;
     206              :         }
     207            1 :         break;
     208            1 :     case kType_AppEpochKey:
     209            1 :         usedBits |= kFlag_UseCurrentEpochKey;
     210            1 :         if (!UsesCurrentEpochKey(keyId))
     211              :         {
     212            1 :             usedBits |= kMask_EpochKeyNumber;
     213              :         }
     214            1 :         break;
     215            1 :     case kType_AppGroupMasterKey:
     216            1 :         usedBits |= kMask_GroupLocalNumber;
     217            1 :         break;
     218            1 :     default:
     219            1 :         return false;
     220              :     }
     221              : 
     222            7 :     if (IncorporatesRootKey(keyId))
     223              :     {
     224            4 :         uint32_t rootKeyId = GetRootKeyId(keyId);
     225            4 :         VerifyOrReturnError(rootKeyId == kFabricRootKey || rootKeyId == kClientRootKey || rootKeyId == kServiceRootKey, false);
     226              :     }
     227              : 
     228            7 :     return (keyId & ~usedBits) == 0;
     229              : }
     230              : 
     231              : /**
     232              :  *  Determine whether a given key ID identifies a key that is suitable for CHIP message encryption.
     233              :  *
     234              :  *  @param[in]   keyId                 CHIP key ID.
     235              :  *  @param[in]   allowLogicalKeys      Specifies whether logical keys IDs (such as the "current" rotating key)
     236              :  *                                     should be considered suitable for message encryption.
     237              :  *  @return      true                  If the identified key can be used to encrypt CHIP messages.
     238              :  *
     239              :  */
     240           12 : bool ChipKeyId::IsMessageSessionId(uint32_t keyId, bool allowLogicalKeys)
     241              : {
     242           12 :     switch (GetType(keyId))
     243              :     {
     244            4 :     case kType_Session:
     245              :     case kType_AppStaticKey:
     246            4 :         return true;
     247            2 :     case kType_AppRotatingKey:
     248            2 :         return allowLogicalKeys || !UsesCurrentEpochKey(keyId);
     249            6 :     default:
     250            6 :         return false;
     251              :     }
     252              : }
     253              : 
     254              : /**
     255              :  * Determines whether two key IDs identify the same key, or in the case of rotating keys, the same
     256              :  * group of keys independent of any particular epoch.
     257              :  *
     258              :  *  @param[in]   keyId1                The first key ID to test.
     259              :  *  @param[in]   keyId2                The second key ID to test.
     260              :  *
     261              :  *  @return                            True if the keys IDs represent the same key.
     262              :  */
     263            5 : bool ChipKeyId::IsSameKeyOrGroup(uint32_t keyId1, uint32_t keyId2)
     264              : {
     265              :     enum
     266              :     {
     267              :         kIgnoreEpochMask = ~(kMask_EpochKeyNumber | kFlag_UseCurrentEpochKey)
     268              :     };
     269              : 
     270              :     // If the key ids are identical then they represent the same key.
     271            5 :     if (keyId1 == keyId2)
     272            2 :         return true;
     273              : 
     274              :     // For rotating keys, treat the key ids as the same if they differ only in their choice of epoch
     275              :     // key number.
     276            3 :     if (IncorporatesEpochKey(keyId1) && !IsAppEpochKey(keyId1) && (keyId1 & kIgnoreEpochMask) == (keyId2 & kIgnoreEpochMask))
     277            0 :         return true;
     278              : 
     279              :     // Otherwise the key ids identify different keys.
     280            3 :     return false;
     281              : }
     282              : 
     283              : /**
     284              :  *  Decode a CHIP key identifier with a descriptive string.
     285              :  *
     286              :  *  @param[in]   keyId     CHIP key ID to decode and for which to return
     287              :  *                         a descriptive string.
     288              :  *
     289              :  *  @return  A pointer to a NULL-terminated string describing the specified key ID.
     290              :  *
     291              :  */
     292           14 : const char * ChipKeyId::DescribeKey(uint32_t keyId)
     293              : {
     294              :     const char * retval;
     295              : 
     296           14 :     switch (GetType(keyId))
     297              :     {
     298            1 :     case kType_None:
     299            1 :         retval = "No Key";
     300            1 :         break;
     301            2 :     case kType_General:
     302            2 :         if (keyId == kFabricSecret)
     303              :         {
     304            1 :             retval = "Fabric Secret";
     305              :         }
     306              :         else
     307              :         {
     308            1 :             retval = "Other General Key";
     309              :         }
     310            2 :         break;
     311            1 :     case kType_Session:
     312            1 :         retval = "Session Key";
     313            1 :         break;
     314            1 :     case kType_AppStaticKey:
     315            1 :         retval = "Application Static Key";
     316            1 :         break;
     317            1 :     case kType_AppRotatingKey:
     318            1 :         retval = "Application Rotating Key";
     319            1 :         break;
     320            4 :     case kType_AppRootKey:
     321            4 :         if (keyId == kFabricRootKey)
     322              :         {
     323            2 :             retval = "Fabric Root Key";
     324              :         }
     325            2 :         else if (keyId == kClientRootKey)
     326              :         {
     327            1 :             retval = "Client Root Key";
     328              :         }
     329            1 :         else if (keyId == kServiceRootKey)
     330              :         {
     331            1 :             retval = "Service Root Key";
     332              :         }
     333              :         else
     334              :         {
     335            0 :             retval = "Other Root Key";
     336              :         }
     337            4 :         break;
     338            1 :     case kType_AppIntermediateKey:
     339            1 :         retval = "Application Intermediate Key";
     340            1 :         break;
     341            1 :     case kType_AppEpochKey:
     342            1 :         retval = "Application Epoch Key";
     343            1 :         break;
     344            1 :     case kType_AppGroupMasterKey:
     345            1 :         retval = "Application Group Master Key";
     346            1 :         break;
     347            1 :     default:
     348            1 :         retval = "Unknown Key Type";
     349              :     }
     350              : 
     351           14 :     return retval;
     352              : }
     353              : 
     354              : } // namespace chip
        

Generated by: LCOV version 2.0-1