| File: | root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c |
| Warning: | line 19, column 14 Excessive padding in 'struct (unnamed at /root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c:19:14)' (8 padding bytes, where 0 is optimal). Optimal fields order: pkcs11Mech, hash, hashSize, consider reordering the fields or adding explicit padding members |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
| 2 | /* |
| 3 | * TLS 1.3 Protocol |
| 4 | * |
| 5 | * This Source Code Form is subject to the terms of the Mozilla Public |
| 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 8 | |
| 9 | #include "keyhi.h" |
| 10 | #include "pk11func.h" |
| 11 | #include "secitem.h" |
| 12 | #include "ssl.h" |
| 13 | #include "sslt.h" |
| 14 | #include "sslerr.h" |
| 15 | #include "sslimpl.h" |
| 16 | |
| 17 | /* This table contains the mapping between TLS hash identifiers and the |
| 18 | * PKCS#11 identifiers */ |
| 19 | static const struct { |
Excessive padding in 'struct (unnamed at /root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c:19:14)' (8 padding bytes, where 0 is optimal). Optimal fields order: pkcs11Mech, hash, hashSize, consider reordering the fields or adding explicit padding members | |
| 20 | SSLHashType hash; |
| 21 | CK_MECHANISM_TYPE pkcs11Mech; |
| 22 | unsigned int hashSize; |
| 23 | } kTlsHkdfInfo[] = { |
| 24 | { ssl_hash_none, 0, 0 }, |
| 25 | { ssl_hash_md5, 0, 0 }, |
| 26 | { ssl_hash_sha1, 0, 0 }, |
| 27 | { ssl_hash_sha224, 0 }, |
| 28 | { ssl_hash_sha256, CKM_SHA2560x00000250UL, 32 }, |
| 29 | { ssl_hash_sha384, CKM_SHA3840x00000260UL, 48 }, |
| 30 | { ssl_hash_sha512, CKM_SHA5120x00000270UL, 64 } |
| 31 | }; |
| 32 | |
| 33 | SECStatus |
| 34 | tls13_HkdfExtract(PK11SymKey *ikm1, PK11SymKey *ikm2, SSLHashType baseHash, |
| 35 | PK11SymKey **prkp) |
| 36 | { |
| 37 | CK_HKDF_PARAMS params; |
| 38 | SECItem paramsi; |
| 39 | PK11SymKey *prk; |
| 40 | static const PRUint8 zeroKeyBuf[HASH_LENGTH_MAX64]; |
| 41 | SECItem zeroKeyItem = { siBuffer, CONST_CAST(PRUint8, zeroKeyBuf)((PRUint8 *)(zeroKeyBuf)), kTlsHkdfInfo[baseHash].hashSize }; |
| 42 | static const PRUint8 zeroSaltBuf[HASH_LENGTH_MAX64]; |
| 43 | SECItem zeroSaltItem = { siBuffer, CONST_CAST(PRUint8, zeroSaltBuf)((PRUint8 *)(zeroSaltBuf)), kTlsHkdfInfo[baseHash].hashSize }; |
| 44 | PK11SlotInfo *slot = NULL((void*)0); |
| 45 | PK11SymKey *newIkm2 = NULL((void*)0); |
| 46 | PK11SymKey *movedIkm1 = NULL((void*)0); |
| 47 | PK11SymKey *movedIkm2 = NULL((void*)0); |
| 48 | SECStatus rv; |
| 49 | |
| 50 | if (!prkp) { |
| 51 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); |
| 52 | return SECFailure; |
| 53 | } |
| 54 | |
| 55 | params.bExtract = CK_TRUE1; |
| 56 | params.bExpand = CK_FALSE0; |
| 57 | params.prfHashMechanism = kTlsHkdfInfo[baseHash].pkcs11Mech; |
| 58 | params.pInfo = NULL((void*)0); |
| 59 | params.ulInfoLen = 0UL; |
| 60 | params.pSalt = NULL((void*)0); |
| 61 | params.ulSaltLen = 0UL; |
| 62 | params.hSaltKey = CK_INVALID_HANDLE0; |
| 63 | params.ulSaltType = 0; |
| 64 | |
| 65 | CK_OBJECT_CLASS ikm2Class = CKO_DATA0x00000000UL; /* in case we don't have it we create one of CKO_DATA type */ |
| 66 | |
| 67 | if (ikm2) { |
| 68 | /* Get the object class of the key(ikm2) */ |
| 69 | SECItem classItem = { siBuffer, NULL((void*)0), 0 }; |
| 70 | rv = PK11_ReadRawAttribute(PK11_TypeSymKey, ikm2, CKA_CLASS0x00000000UL, &classItem); |
| 71 | if (rv != SECSuccess || classItem.len != sizeof(CK_OBJECT_CLASS)) { |
| 72 | SECITEM_FreeItemSECITEM_FreeItem_Util(&classItem, PR_FALSE0); |
| 73 | goto cleanup; |
| 74 | } |
| 75 | memcpy(&ikm2Class, classItem.data, sizeof(ikm2Class)); |
| 76 | SECITEM_FreeItemSECITEM_FreeItem_Util(&classItem, PR_FALSE0); |
| 77 | } else { |
| 78 | /* A zero ikm2 is a key of hash-length 0s. */ |
| 79 | /* if we have ikm1, put the zero key in the same slot */ |
| 80 | if (ikm1) { |
| 81 | slot = PK11_GetSlotFromKey(ikm1); |
| 82 | } |
| 83 | |
| 84 | if (!slot || PK11_DoesMechanism(slot, CKM_HKDF_DERIVE0x0000402aUL) == PR_FALSE0) { |
| 85 | /* fallback if ikm1 is not provided or the slot doesn't support the mechanism*/ |
| 86 | if (slot) { |
| 87 | PK11_FreeSlot(slot); |
| 88 | } |
| 89 | slot = PK11_GetBestSlot(CKM_HKDF_DERIVE0x0000402aUL, NULL((void*)0)); |
| 90 | } |
| 91 | |
| 92 | if (!slot) { |
| 93 | rv = SECFailure; |
| 94 | goto cleanup; |
| 95 | } |
| 96 | |
| 97 | newIkm2 = PK11_ImportDataKey(slot, CKM_HKDF_DERIVE0x0000402aUL, PK11_OriginUnwrap, |
| 98 | CKA_DERIVE0x0000010CUL, &zeroKeyItem, NULL((void*)0)); |
| 99 | if (!newIkm2) { |
| 100 | rv = SECFailure; |
| 101 | goto cleanup; |
| 102 | } |
| 103 | ikm2 = newIkm2; |
| 104 | } |
| 105 | PORT_Assert(ikm2)((ikm2) ? ((void)0) : PR_Assert("ikm2", "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c" , 105)); |
| 106 | |
| 107 | if (!ikm1) { |
| 108 | if (ikm2Class == CKO_DATA0x00000000UL) { |
| 109 | /* since PKCS #11 v3.0 it is mandatory to provide CKF_HKDF_SALT_DATA |
| 110 | * if key(ikm2) is of type CKO_DATA. see. Section 6.62.3 */ |
| 111 | params.pSalt = zeroSaltItem.data; |
| 112 | params.ulSaltLen = zeroSaltItem.len; |
| 113 | params.ulSaltType = CKF_HKDF_SALT_DATA0x00000002UL; |
| 114 | } else { |
| 115 | /* PKCS #11 v3.0 has and explict NULL value, which equates to |
| 116 | * a sequence of zeros equal in length to the HMAC. */ |
| 117 | params.ulSaltType = CKF_HKDF_SALT_NULL0x00000001UL; |
| 118 | } |
| 119 | } else { |
| 120 | /* PKCS #11 v3.0 can take the salt as a key handle */ |
| 121 | rv = PK11_SymKeysToSameSlot(CKM_HKDF_DERIVE0x0000402aUL, |
| 122 | CKA_DERIVE0x0000010CUL, CKA_DERIVE0x0000010CUL, |
| 123 | ikm2, ikm1, &movedIkm2, &movedIkm1); |
| 124 | |
| 125 | if (rv != SECSuccess) { |
| 126 | /* couldn't move the keys, try extracting the salt */ |
| 127 | SECItem *salt; |
| 128 | rv = PK11_ExtractKeyValue(ikm1); |
| 129 | if (rv != SECSuccess) { |
| 130 | goto cleanup; |
| 131 | } |
| 132 | salt = PK11_GetKeyData(ikm1); |
| 133 | if (!salt) { |
| 134 | rv = SECFailure; |
| 135 | goto cleanup; |
| 136 | } |
| 137 | PORT_Assert(salt->len > 0)((salt->len > 0) ? ((void)0) : PR_Assert("salt->len > 0" , "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c", 137 )); |
| 138 | /* Set up for Salt as Data instead of Salt as key */ |
| 139 | params.pSalt = salt->data; |
| 140 | params.ulSaltLen = salt->len; |
| 141 | params.ulSaltType = CKF_HKDF_SALT_DATA0x00000002UL; |
| 142 | } else { |
| 143 | /* use the moved keys */ |
| 144 | if (movedIkm1) { |
| 145 | ikm1 = movedIkm1; |
| 146 | } |
| 147 | if (movedIkm2) { |
| 148 | ikm2 = movedIkm2; |
| 149 | } |
| 150 | |
| 151 | params.hSaltKey = PK11_GetSymKeyHandle(ikm1); |
| 152 | params.ulSaltType = CKF_HKDF_SALT_KEY0x00000004UL; |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | paramsi.data = (unsigned char *)¶ms; |
| 157 | paramsi.len = sizeof(params); |
| 158 | |
| 159 | PORT_Assert(kTlsHkdfInfo[baseHash].pkcs11Mech)((kTlsHkdfInfo[baseHash].pkcs11Mech) ? ((void)0) : PR_Assert( "kTlsHkdfInfo[baseHash].pkcs11Mech", "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c" , 159)); |
| 160 | PORT_Assert(kTlsHkdfInfo[baseHash].hashSize)((kTlsHkdfInfo[baseHash].hashSize) ? ((void)0) : PR_Assert("kTlsHkdfInfo[baseHash].hashSize" , "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c", 160 )); |
| 161 | PORT_Assert(kTlsHkdfInfo[baseHash].hash == baseHash)((kTlsHkdfInfo[baseHash].hash == baseHash) ? ((void)0) : PR_Assert ("kTlsHkdfInfo[baseHash].hash == baseHash", "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c" , 161)); |
| 162 | |
| 163 | if (params.ulSaltType == CKF_HKDF_SALT_DATA0x00000002UL) { |
| 164 | PORT_Assert(params.hSaltKey == CK_INVALID_HANDLE)((params.hSaltKey == 0) ? ((void)0) : PR_Assert("params.hSaltKey == CK_INVALID_HANDLE" , "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c", 164 )); |
| 165 | PORT_Assert(params.pSalt != NULL)((params.pSalt != ((void*)0)) ? ((void)0) : PR_Assert("params.pSalt != NULL" , "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c", 165 )); |
| 166 | } |
| 167 | if (params.ulSaltType == CKF_HKDF_SALT_NULL0x00000001UL) { |
| 168 | PORT_Assert(ikm2Class != CKO_DATA)((ikm2Class != 0x00000000UL) ? ((void)0) : PR_Assert("ikm2Class != CKO_DATA" , "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c", 168 )); |
| 169 | PORT_Assert(params.hSaltKey == CK_INVALID_HANDLE)((params.hSaltKey == 0) ? ((void)0) : PR_Assert("params.hSaltKey == CK_INVALID_HANDLE" , "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c", 169 )); |
| 170 | PORT_Assert(params.pSalt == NULL)((params.pSalt == ((void*)0)) ? ((void)0) : PR_Assert("params.pSalt == NULL" , "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c", 170 )); |
| 171 | PORT_Assert(params.ulSaltLen == 0UL)((params.ulSaltLen == 0UL) ? ((void)0) : PR_Assert("params.ulSaltLen == 0UL" , "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c", 171 )); |
| 172 | } |
| 173 | if (params.ulSaltType == CKF_HKDF_SALT_KEY0x00000004UL) { |
| 174 | PORT_Assert(params.hSaltKey != CK_INVALID_HANDLE)((params.hSaltKey != 0) ? ((void)0) : PR_Assert("params.hSaltKey != CK_INVALID_HANDLE" , "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c", 174 )); |
| 175 | PORT_Assert(params.pSalt == NULL)((params.pSalt == ((void*)0)) ? ((void)0) : PR_Assert("params.pSalt == NULL" , "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c", 175 )); |
| 176 | PORT_Assert(params.ulSaltLen == 0UL)((params.ulSaltLen == 0UL) ? ((void)0) : PR_Assert("params.ulSaltLen == 0UL" , "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c", 176 )); |
| 177 | } |
| 178 | |
| 179 | PRINT_BUF(50, (NULL, "HKDF Extract: IKM1/Salt", params.pSalt, params.ulSaltLen))if (ssl_trace >= (50)) ssl_PrintBuf (((void*)0), "HKDF Extract: IKM1/Salt" , params.pSalt, params.ulSaltLen); |
| 180 | PRINT_KEY(50, (NULL, "HKDF Extract: IKM2", ikm2))if (ssl_trace >= (50)) ssl_PrintKey (((void*)0), "HKDF Extract: IKM2" , ikm2); |
| 181 | |
| 182 | prk = PK11_Derive(ikm2, CKM_HKDF_DERIVE0x0000402aUL, ¶msi, CKM_HKDF_DERIVE0x0000402aUL, |
| 183 | CKA_DERIVE0x0000010CUL, 0); |
| 184 | |
| 185 | if (!prk) { |
| 186 | rv = SECFailure; |
| 187 | goto cleanup; |
| 188 | } |
| 189 | |
| 190 | PRINT_KEY(50, (NULL, "HKDF Extract", prk))if (ssl_trace >= (50)) ssl_PrintKey (((void*)0), "HKDF Extract" , prk); |
| 191 | *prkp = prk; |
| 192 | rv = SECSuccess; |
| 193 | |
| 194 | cleanup: |
| 195 | PK11_FreeSymKey(movedIkm1); |
| 196 | PK11_FreeSymKey(movedIkm2); |
| 197 | PK11_FreeSymKey(newIkm2); |
| 198 | if (slot) |
| 199 | PK11_FreeSlot(slot); |
| 200 | return rv; |
| 201 | } |
| 202 | |
| 203 | SECStatus |
| 204 | tls13_HkdfExpandLabelGeneral(CK_MECHANISM_TYPE deriveMech, PK11SymKey *prk, |
| 205 | SSLHashType baseHash, |
| 206 | const PRUint8 *handshakeHash, unsigned int handshakeHashLen, |
| 207 | const char *label, unsigned int labelLen, |
| 208 | CK_MECHANISM_TYPE algorithm, unsigned int keySize, |
| 209 | SSLProtocolVariant variant, PK11SymKey **keyp) |
| 210 | { |
| 211 | CK_HKDF_PARAMS params; |
| 212 | SECItem paramsi = { siBuffer, NULL((void*)0), 0 }; |
| 213 | /* Size of info array needs to be big enough to hold the maximum Prefix, |
| 214 | * Label, plus HandshakeHash. If it's ever to small, the code will abort. |
| 215 | */ |
| 216 | PRUint8 info[256]; |
| 217 | sslBuffer infoBuf = SSL_BUFFER(info){ info, 0, sizeof(info), 1 }; |
| 218 | PK11SymKey *derived; |
| 219 | SECStatus rv; |
| 220 | const char *kLabelPrefixTls = "tls13 "; |
| 221 | const char *kLabelPrefixDtls = "dtls13"; |
| 222 | const unsigned int kLabelPrefixLen = |
| 223 | (variant == ssl_variant_stream) ? strlen(kLabelPrefixTls) : strlen(kLabelPrefixDtls); |
| 224 | const char *kLabelPrefix = |
| 225 | (variant == ssl_variant_stream) ? kLabelPrefixTls : kLabelPrefixDtls; |
| 226 | CK_FLAGS flags = 0; |
| 227 | CK_KEY_TYPE targetKeyType = PK11_GetKeyType(algorithm, keySize); |
| 228 | |
| 229 | /* PKCS #11 Mechanisms v3.0 Sec 2.62.4: CKM_HKDF_DATA outputs CKO_DATA. |
| 230 | * Sec 4.5.2: CKO_DATA objects cannot hold crypto operation flags */ |
| 231 | if (deriveMech != CKM_HKDF_DATA0x0000402bUL) { |
| 232 | flags |= CKF_SIGN0x00000800UL | CKF_VERIFY0x00002000; |
| 233 | |
| 234 | /* PKCS #11 v3.0 Sec 2.8.2: CKK_GENERIC_SECRET and CKK_HKDF |
| 235 | * explicitly do not support encrypt/decrypt operations. */ |
| 236 | if (targetKeyType != CKK_GENERIC_SECRET0x00000010UL && targetKeyType != CKK_HKDF0x00000042UL) { |
| 237 | flags |= CKF_ENCRYPT0x00000100UL | CKF_DECRYPT0x00000200UL; |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | PORT_Assert(prk)((prk) ? ((void)0) : PR_Assert("prk", "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c" , 241)); |
| 242 | PORT_Assert(keyp)((keyp) ? ((void)0) : PR_Assert("keyp", "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c" , 242)); |
| 243 | if ((handshakeHashLen > 255) || |
| 244 | (handshakeHash == NULL((void*)0) && handshakeHashLen > 0) || |
| 245 | (labelLen > 255 - kLabelPrefixLen)) { |
| 246 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); |
| 247 | return SECFailure; |
| 248 | } |
| 249 | |
| 250 | /* |
| 251 | * [draft-ietf-tls-tls13-11] Section 7.1: |
| 252 | * |
| 253 | * HKDF-Expand-Label(Secret, Label, HashValue, Length) = |
| 254 | * HKDF-Expand(Secret, HkdfLabel, Length) |
| 255 | * |
| 256 | * Where HkdfLabel is specified as: |
| 257 | * |
| 258 | * struct HkdfLabel { |
| 259 | * uint16 length; |
| 260 | * opaque label<9..255>; |
| 261 | * opaque hash_value<0..255>; |
| 262 | * }; |
| 263 | * |
| 264 | * Where: |
| 265 | * - HkdfLabel.length is Length |
| 266 | * - HkdfLabel.hash_value is HashValue. |
| 267 | * - HkdfLabel.label is "TLS 1.3, " + Label |
| 268 | * |
| 269 | */ |
| 270 | rv = sslBuffer_AppendNumber(&infoBuf, keySize, 2); |
| 271 | if (rv != SECSuccess) { |
| 272 | return SECFailure; |
| 273 | } |
| 274 | rv = sslBuffer_AppendNumber(&infoBuf, labelLen + kLabelPrefixLen, 1); |
| 275 | if (rv != SECSuccess) { |
| 276 | return SECFailure; |
| 277 | } |
| 278 | rv = sslBuffer_Append(&infoBuf, kLabelPrefix, kLabelPrefixLen); |
| 279 | if (rv != SECSuccess) { |
| 280 | return SECFailure; |
| 281 | } |
| 282 | rv = sslBuffer_Append(&infoBuf, label, labelLen); |
| 283 | if (rv != SECSuccess) { |
| 284 | return SECFailure; |
| 285 | } |
| 286 | rv = sslBuffer_AppendVariable(&infoBuf, handshakeHash, handshakeHashLen, 1); |
| 287 | if (rv != SECSuccess) { |
| 288 | return SECFailure; |
| 289 | } |
| 290 | |
| 291 | params.bExtract = CK_FALSE0; |
| 292 | params.bExpand = CK_TRUE1; |
| 293 | params.prfHashMechanism = kTlsHkdfInfo[baseHash].pkcs11Mech; |
| 294 | params.pInfo = SSL_BUFFER_BASE(&infoBuf)((&infoBuf)->buf); |
| 295 | params.ulInfoLen = SSL_BUFFER_LEN(&infoBuf)((&infoBuf)->len); |
| 296 | paramsi.data = (unsigned char *)¶ms; |
| 297 | paramsi.len = sizeof(params); |
| 298 | derived = PK11_DeriveWithFlags(prk, deriveMech, |
| 299 | ¶msi, algorithm, |
| 300 | CKA_DERIVE0x0000010CUL, keySize, |
| 301 | flags); |
| 302 | if (!derived) { |
| 303 | return SECFailure; |
| 304 | } |
| 305 | |
| 306 | *keyp = derived; |
| 307 | |
| 308 | #ifdef TRACE |
| 309 | if (ssl_trace >= 50) { |
| 310 | /* Make sure the label is null terminated. */ |
| 311 | char labelStr[100]; |
| 312 | PORT_Memcpymemcpy(labelStr, label, labelLen); |
| 313 | labelStr[labelLen] = 0; |
| 314 | SSL_TRC(50, ("HKDF Expand: label='tls13 %s',requested length=%d",if (ssl_trace >= (50)) ssl_Trace ("HKDF Expand: label='tls13 %s',requested length=%d" , labelStr, keySize) |
| 315 | labelStr, keySize))if (ssl_trace >= (50)) ssl_Trace ("HKDF Expand: label='tls13 %s',requested length=%d" , labelStr, keySize); |
| 316 | } |
| 317 | PRINT_KEY(50, (NULL, "PRK", prk))if (ssl_trace >= (50)) ssl_PrintKey (((void*)0), "PRK", prk ); |
| 318 | PRINT_BUF(50, (NULL, "Hash", handshakeHash, handshakeHashLen))if (ssl_trace >= (50)) ssl_PrintBuf (((void*)0), "Hash", handshakeHash , handshakeHashLen); |
| 319 | PRINT_BUF(50, (NULL, "Info", SSL_BUFFER_BASE(&infoBuf),if (ssl_trace >= (50)) ssl_PrintBuf (((void*)0), "Info", ( (&infoBuf)->buf), ((&infoBuf)->len)) |
| 320 | SSL_BUFFER_LEN(&infoBuf)))if (ssl_trace >= (50)) ssl_PrintBuf (((void*)0), "Info", ( (&infoBuf)->buf), ((&infoBuf)->len)); |
| 321 | PRINT_KEY(50, (NULL, "Derived key", derived))if (ssl_trace >= (50)) ssl_PrintKey (((void*)0), "Derived key" , derived); |
| 322 | #endif |
| 323 | |
| 324 | return SECSuccess; |
| 325 | } |
| 326 | |
| 327 | SECStatus |
| 328 | tls13_HkdfExpandLabel(PK11SymKey *prk, SSLHashType baseHash, |
| 329 | const PRUint8 *handshakeHash, unsigned int handshakeHashLen, |
| 330 | const char *label, unsigned int labelLen, |
| 331 | CK_MECHANISM_TYPE algorithm, unsigned int keySize, |
| 332 | SSLProtocolVariant variant, PK11SymKey **keyp) |
| 333 | { |
| 334 | return tls13_HkdfExpandLabelGeneral(CKM_HKDF_DERIVE0x0000402aUL, prk, baseHash, |
| 335 | handshakeHash, handshakeHashLen, |
| 336 | label, labelLen, algorithm, keySize, |
| 337 | variant, keyp); |
| 338 | } |
| 339 | |
| 340 | SECStatus |
| 341 | tls13_HkdfExpandLabelRaw(PK11SymKey *prk, SSLHashType baseHash, |
| 342 | const PRUint8 *handshakeHash, unsigned int handshakeHashLen, |
| 343 | const char *label, unsigned int labelLen, |
| 344 | SSLProtocolVariant variant, unsigned char *output, |
| 345 | unsigned int outputLen) |
| 346 | { |
| 347 | PK11SymKey *derived = NULL((void*)0); |
| 348 | SECItem *rawkey; |
| 349 | SECStatus rv; |
| 350 | |
| 351 | /* the result is not really a key, it's a data object */ |
| 352 | rv = tls13_HkdfExpandLabelGeneral(CKM_HKDF_DATA0x0000402bUL, prk, baseHash, |
| 353 | handshakeHash, handshakeHashLen, |
| 354 | label, labelLen, CKM_HKDF_DERIVE0x0000402aUL, outputLen, |
| 355 | variant, &derived); |
| 356 | if (rv != SECSuccess || !derived) { |
| 357 | goto abort; |
| 358 | } |
| 359 | |
| 360 | rv = PK11_ExtractKeyValue(derived); |
| 361 | if (rv != SECSuccess) { |
| 362 | goto abort; |
| 363 | } |
| 364 | |
| 365 | rawkey = PK11_GetKeyData(derived); |
| 366 | if (!rawkey) { |
| 367 | goto abort; |
| 368 | } |
| 369 | |
| 370 | PORT_Assert(rawkey->len == outputLen)((rawkey->len == outputLen) ? ((void)0) : PR_Assert("rawkey->len == outputLen" , "/root/firefox-clang/security/nss/lib/ssl/tls13hkdf.c", 370 )); |
| 371 | memcpy(output, rawkey->data, outputLen); |
| 372 | PK11_FreeSymKey(derived); |
| 373 | |
| 374 | return SECSuccess; |
| 375 | |
| 376 | abort: |
| 377 | if (derived) { |
| 378 | PK11_FreeSymKey(derived); |
| 379 | } |
| 380 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); |
| 381 | return SECFailure; |
| 382 | } |