3.1.4.1.2 Generating a Group Key

This section specifies the processing rules for generating a group key for a given security descriptor, root key identifier, and group key identifier. The following notational conventions are used in the processing rules in this section:

  • SD — is used to denote the specified security descriptor, expressed in self-relative form, as specified in [MS-DTYP] section 2.4.6.

  • RKID — denotes the specified root key identifier, represented in the binary format specified in [MS-DTYP] section 2.3.4.2.

  • RK — denotes the selected root key object corresponding to the root key identifier RKID. The attributes of the root key object are denoted in the form RK.attributeName, where attributeName is a particular Active Directory attribute of the root key object, as specified in section 3.1.1. For example, RK.msKds-Version indicates the version of the root key RK.

  • (L0, L1, L2) — refers to the specified group key identifier.

  • Key(SD, RK, L0, L1, L2) — denotes the group seed key for security descriptor SD, root key object RK, and group key identifier (L0, L1, L2).

  • PubKey(SD, RK, L0, L1, L2) — denotes the group public key for security descriptor SD, root key object RK, and group key identifier (L0, L1, L2).

  • PrivKey(SD, RK, L0, L1, L2) — denotes the group private key for security descriptor SD, root key object RK, and group key identifier (L0, L1, L2).

  • KDF(HashAlg, KI, Label, Context, L) — denotes an execution of the [SP800-108] KDF in counter mode ([SP800-108] section 5.1) by using the Hash Message Authentication Code (HMAC) specified in [FIPS198-1], with HashAlg as the underlying hash algorithm (as the PRF), and with KI, Label, Context, and L representing the identically named parameters specified in [SP800-108] section 5.

  • SHA-1, SHA-256, SHA-384, and SHA-512 — denote the hash algorithms of the same names, as specified in [FIPS180-3].

  • || — this symbol refers to the concatenation operator.

In addition, the following assumptions apply unless specified otherwise:

  • Each string constant is assumed to be a null-terminated Unicode string.

  • All integer constants and variables are assumed to be 32-bit integers in little-endian format.

To generate the group key, the server MUST first check the root key configuration attributes of the RK object.

  1. Check that RK.msKds-Version is equal to 1. Otherwise, return an error.

  2. Check that RK.msKds-KDF-AlgorithmID is equal to "SP800_108_CTR_HMAC".

    Protocol behavior for other values of the KDF algorithm ID is undefined.<1>

  3. Check that RK.msKds-KDF-Param is in the format specified in section 2.2.1, and that the hash algorithm name therein is equal to one of the values that follow.

    Protocol behavior for other values of the KDF parameter attribute is undefined.<2>

    • If RK.msKds-KDF-Param is equal to "SHA1", set HashAlg to SHA-1.

    • If RK.msKds-KDF-Param is equal to "SHA256", set HashAlg to SHA-256.

    • If RK.msKds-KDF-Param is equal to "SHA384", set HashAlg to SHA-384.

    • If RK.msKds-KDF-Param is equal to "SHA512", set HashAlg to SHA-512.

  4. To derive an L0 seed key with a group key identifier (L0, -1, -1), the server MUST perform the following computation:

    Key(SD, RK, L0, -1, -1) = KDF(HashAlg, RK.msKds-RootKeyData, "KDS service", RKID || L0 || 0xffffffff || 0xffffffff, 512)

  5. To derive an L1 seed key with a group key identifier (L0, 31, -1), the server MUST proceed as follows:

    Key(SD, RK, L0, 31, -1) = KDF(HashAlg, Key(SD, RK, L0, -1, -1), "KDS service", RKID || L0 || 31 || 0xffffffff || SD, 512)

  6. To derive an L1 seed key with group key identifier (L0, n, -1), where n is an integer between 0 and 30 inclusive, the server MUST proceed as follows:

    Key(SD, RK, L0, n, -1) = KDF(HashAlg, Key(SD, RK, L0, n+1, -1), "KDS service", RKID || L0 || n || 0xffffffff, 512)

  7. To derive an L2 seed key with a group key identifier (L0, L1, n), where n is an integer between 0 and 31 inclusive, the server MUST proceed as follows:

    Key(SD, RK, L0, L1, n) = KDF(HashAlg, Key(SD, RK, L0, L1, n+1), "KDS service", RKID || L0 || L1|| n, 512); where Key(SD, RK, L0, L1, 32) = Key(SD, RK, L0, L1, -1)

To derive a group public key with a group key identifier (L0, L1, L2), the server MUST proceed as follows:

  1. First, the server MUST validate the root key configuration attributes related to public keys:

    • If RK.msKds-SecretAgreement-AlgorithmID is equal to "DH", RK.msKds-SecretAgreement-Param MUST be in the format specified in section 2.2.2, and the Key length field of RK.msKds-SecretAgreement-Param MUST be equal to RK.msKds-PublicKey-Length.

    • If RK.msKds-SecretAgreement-AlgorithmID is equal to "ECDH_P256", "ECDH_P384" or "ECDH_P521", the RK.msKds-SecretAgreement-Param MUST be NULL.

      Protocol behavior for other values of the secret agreement algorithm name and parameter attributes is undefined.<3>

  2. Having validated the root key configuration, the server MUST then compute the group private key in the following manner:

    PrivKey(SD, RK, L0, L1, L2) = KDF(HashAlg, Key(SD, RK, L0, L1, L2), "KDS service", RK.msKds-SecretAgreement-AlgorithmID, RK.msKds-PrivateKey-Length)

    Note  If RK.msKds-PrivateKey-Length is not a multiple of 8, it needs to be rounded up to the next multiple of 8.

  3. Lastly, the server MUST compute the group public key PubKey(SD, RK, L0, L1, L2) as follows:

    • If RK.msKds-SecretAgreement-AlgorithmID is equal to "DH", the server MUST compute PubKey(SD, RK, L0, L1, L2) by using the method specified in [SP800-56A] section 5.6.1.1, with the group parameters specified in RK.msKds-SecretAgreement-Param, and with PrivKey(SD, RK, L0, L1, L2) as the private key.

    • If RK.msKds-SecretAgreement-AlgorithmID is equal to "ECDH_P256", "ECDH_P384", or "ECDH_P521", the server MUST compute PubKey(SD, RK, L0, L1, L2) by using the method specified in [SP800-56A] section 5.6.1.2, with PrivKey(SD, RK, L0, L1, L2) as the private key d, and by using the domain parameters from [FIPS186] Appendix D.1.2.3, D.1.2.4, or D.1.2.5, respectively.