Private/Crypto/New-PukAesKey.ps1

function New-PukAesKey {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Pure in-memory computation (generates and returns AES/HMAC key material); changes no external or persistent state.')]
    [CmdletBinding()]
    [OutputType([psobject])]
    param()

    $aes = [System.Security.Cryptography.Aes]::Create()
    $rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
    try {
        $aes.KeySize = 256
        $aes.GenerateKey()
        $aes.GenerateIV()

        # Independent key for the Encrypt-then-MAC HMAC-SHA256 tag (never reuse the AES key
        # for authentication -- see Protect-PukAdAttributeValue for why GCM isn't used here).
        $hmacKey = [byte[]]::new(32)
        $rng.GetBytes($hmacKey)

        return [PSCustomObject]@{
            Key     = $aes.Key
            IV      = $aes.IV
            HmacKey = $hmacKey
        }
    }
    finally {
        $aes.Dispose()
        $rng.Dispose()
    }
}