1 /* 2 * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.crypto.provider; 27 28 import java.util.Arrays; 29 30 import java.security.*; 31 import java.security.spec.AlgorithmParameterSpec; 32 33 import javax.crypto.*; 34 import javax.crypto.spec.SecretKeySpec; 35 36 import sun.security.internal.spec.TlsPrfParameterSpec; 37 38 /** 39 * KeyGenerator implementation for the TLS PRF function. 40 * <p> 41 * This class duplicates the HMAC functionality (RFC 2104) with 42 * performance optimizations (e.g. XOR'ing keys with padding doesn't 43 * need to be redone for each HMAC operation). 44 * 45 * @author Andreas Sterbenz 46 * @since 1.6 47 */ 48 abstract class TlsPrfGenerator extends KeyGeneratorSpi { 49 50 // magic constants and utility functions, also used by other files 51 // in this package 52 53 private static final byte[] B0 = new byte[0]; 54 55 static final byte[] LABEL_MASTER_SECRET = // "master secret" 56 { 109, 97, 115, 116, 101, 114, 32, 115, 101, 99, 114, 101, 116 }; 57 58 static final byte[] LABEL_EXTENDED_MASTER_SECRET = 59 // "extended master secret" 60 { 101, 120, 116, 101, 110, 100, 101, 100, 32, 109, 97, 115, 116, 61 101, 114, 32, 115, 101, 99, 114, 101, 116 }; 62 63 static final byte[] LABEL_KEY_EXPANSION = // "key expansion" 64 { 107, 101, 121, 32, 101, 120, 112, 97, 110, 115, 105, 111, 110 }; 65 66 static final byte[] LABEL_CLIENT_WRITE_KEY = // "client write key" 67 { 99, 108, 105, 101, 110, 116, 32, 119, 114, 105, 116, 101, 32, 68 107, 101, 121 }; 69 70 static final byte[] LABEL_SERVER_WRITE_KEY = // "server write key" 71 { 115, 101, 114, 118, 101, 114, 32, 119, 114, 105, 116, 101, 32, 72 107, 101, 121 }; 73 74 static final byte[] LABEL_IV_BLOCK = // "IV block" 75 { 73, 86, 32, 98, 108, 111, 99, 107 }; 76 77 /* 78 * TLS HMAC "inner" and "outer" padding. This isn't a function 79 * of the digest algorithm. 80 */ 81 private static final byte[] HMAC_ipad64 = genPad((byte)0x36, 64); 82 private static final byte[] HMAC_ipad128 = genPad((byte)0x36, 128); 83 private static final byte[] HMAC_opad64 = genPad((byte)0x5c, 64); 84 private static final byte[] HMAC_opad128 = genPad((byte)0x5c, 128); 85 86 // SSL3 magic mix constants ("A", "BB", "CCC", ...) 87 static final byte[][] SSL3_CONST = genConst(); 88 genPad(byte b, int count)89 static byte[] genPad(byte b, int count) { 90 byte[] padding = new byte[count]; 91 Arrays.fill(padding, b); 92 return padding; 93 } 94 concat(byte[] b1, byte[] b2)95 static byte[] concat(byte[] b1, byte[] b2) { 96 int n1 = b1.length; 97 int n2 = b2.length; 98 byte[] b = new byte[n1 + n2]; 99 System.arraycopy(b1, 0, b, 0, n1); 100 System.arraycopy(b2, 0, b, n1, n2); 101 return b; 102 } 103 genConst()104 private static byte[][] genConst() { 105 int n = 10; 106 byte[][] arr = new byte[n][]; 107 for (int i = 0; i < n; i++) { 108 byte[] b = new byte[i + 1]; 109 Arrays.fill(b, (byte)('A' + i)); 110 arr[i] = b; 111 } 112 return arr; 113 } 114 115 // PRF implementation 116 117 private static final String MSG = "TlsPrfGenerator must be " 118 + "initialized using a TlsPrfParameterSpec"; 119 120 @SuppressWarnings("deprecation") 121 private TlsPrfParameterSpec spec; 122 TlsPrfGenerator()123 public TlsPrfGenerator() { 124 } 125 engineInit(SecureRandom random)126 protected void engineInit(SecureRandom random) { 127 throw new InvalidParameterException(MSG); 128 } 129 130 @SuppressWarnings("deprecation") engineInit(AlgorithmParameterSpec params, SecureRandom random)131 protected void engineInit(AlgorithmParameterSpec params, 132 SecureRandom random) throws InvalidAlgorithmParameterException { 133 if (params instanceof TlsPrfParameterSpec == false) { 134 throw new InvalidAlgorithmParameterException(MSG); 135 } 136 this.spec = (TlsPrfParameterSpec)params; 137 SecretKey key = spec.getSecret(); 138 if ((key != null) && ("RAW".equals(key.getFormat()) == false)) { 139 throw new InvalidAlgorithmParameterException( 140 "Key encoding format must be RAW"); 141 } 142 } 143 engineInit(int keysize, SecureRandom random)144 protected void engineInit(int keysize, SecureRandom random) { 145 throw new InvalidParameterException(MSG); 146 } 147 engineGenerateKey0(boolean tls12)148 SecretKey engineGenerateKey0(boolean tls12) { 149 if (spec == null) { 150 throw new IllegalStateException( 151 "TlsPrfGenerator must be initialized"); 152 } 153 SecretKey key = spec.getSecret(); 154 byte[] secret = (key == null) ? null : key.getEncoded(); 155 try { 156 byte[] labelBytes = spec.getLabel().getBytes("UTF8"); 157 int n = spec.getOutputLength(); 158 byte[] prfBytes = (tls12 ? 159 doTLS12PRF(secret, labelBytes, spec.getSeed(), n, 160 spec.getPRFHashAlg(), spec.getPRFHashLength(), 161 spec.getPRFBlockSize()) : 162 doTLS10PRF(secret, labelBytes, spec.getSeed(), n)); 163 return new SecretKeySpec(prfBytes, "TlsPrf"); 164 } catch (GeneralSecurityException e) { 165 throw new ProviderException("Could not generate PRF", e); 166 } catch (java.io.UnsupportedEncodingException e) { 167 throw new ProviderException("Could not generate PRF", e); 168 } 169 } 170 doTLS12PRF(byte[] secret, byte[] labelBytes, byte[] seed, int outputLength, String prfHash, int prfHashLength, int prfBlockSize)171 static byte[] doTLS12PRF(byte[] secret, byte[] labelBytes, 172 byte[] seed, int outputLength, 173 String prfHash, int prfHashLength, int prfBlockSize) 174 throws NoSuchAlgorithmException, DigestException { 175 if (prfHash == null) { 176 throw new NoSuchAlgorithmException("Unspecified PRF algorithm"); 177 } 178 MessageDigest prfMD = MessageDigest.getInstance(prfHash); 179 return doTLS12PRF(secret, labelBytes, seed, outputLength, 180 prfMD, prfHashLength, prfBlockSize); 181 } 182 doTLS12PRF(byte[] secret, byte[] labelBytes, byte[] seed, int outputLength, MessageDigest mdPRF, int mdPRFLen, int mdPRFBlockSize)183 static byte[] doTLS12PRF(byte[] secret, byte[] labelBytes, 184 byte[] seed, int outputLength, 185 MessageDigest mdPRF, int mdPRFLen, int mdPRFBlockSize) 186 throws DigestException { 187 188 if (secret == null) { 189 secret = B0; 190 } 191 192 // If we have a long secret, digest it first. 193 if (secret.length > mdPRFBlockSize) { 194 secret = mdPRF.digest(secret); 195 } 196 197 byte[] output = new byte[outputLength]; 198 byte [] ipad; 199 byte [] opad; 200 201 switch (mdPRFBlockSize) { 202 case 64: 203 ipad = HMAC_ipad64.clone(); 204 opad = HMAC_opad64.clone(); 205 break; 206 case 128: 207 ipad = HMAC_ipad128.clone(); 208 opad = HMAC_opad128.clone(); 209 break; 210 default: 211 throw new DigestException("Unexpected block size."); 212 } 213 214 // P_HASH(Secret, label + seed) 215 expand(mdPRF, mdPRFLen, secret, 0, secret.length, labelBytes, 216 seed, output, ipad, opad); 217 218 return output; 219 } 220 doTLS10PRF(byte[] secret, byte[] labelBytes, byte[] seed, int outputLength)221 static byte[] doTLS10PRF(byte[] secret, byte[] labelBytes, 222 byte[] seed, int outputLength) throws NoSuchAlgorithmException, 223 DigestException { 224 MessageDigest md5 = MessageDigest.getInstance("MD5"); 225 MessageDigest sha = MessageDigest.getInstance("SHA1"); 226 return doTLS10PRF(secret, labelBytes, seed, outputLength, md5, sha); 227 } 228 doTLS10PRF(byte[] secret, byte[] labelBytes, byte[] seed, int outputLength, MessageDigest md5, MessageDigest sha)229 static byte[] doTLS10PRF(byte[] secret, byte[] labelBytes, 230 byte[] seed, int outputLength, MessageDigest md5, 231 MessageDigest sha) throws DigestException { 232 /* 233 * Split the secret into two halves S1 and S2 of same length. 234 * S1 is taken from the first half of the secret, S2 from the 235 * second half. 236 * Their length is created by rounding up the length of the 237 * overall secret divided by two; thus, if the original secret 238 * is an odd number of bytes long, the last byte of S1 will be 239 * the same as the first byte of S2. 240 * 241 * Note: Instead of creating S1 and S2, we determine the offset into 242 * the overall secret where S2 starts. 243 */ 244 245 if (secret == null) { 246 secret = B0; 247 } 248 int off = secret.length >> 1; 249 int seclen = off + (secret.length & 1); 250 251 byte[] secKey = secret; 252 int keyLen = seclen; 253 byte[] output = new byte[outputLength]; 254 255 // P_MD5(S1, label + seed) 256 // If we have a long secret, digest it first. 257 if (seclen > 64) { // 64: block size of HMAC-MD5 258 md5.update(secret, 0, seclen); 259 secKey = md5.digest(); 260 keyLen = secKey.length; 261 } 262 expand(md5, 16, secKey, 0, keyLen, labelBytes, seed, output, 263 HMAC_ipad64.clone(), HMAC_opad64.clone()); 264 265 // P_SHA-1(S2, label + seed) 266 // If we have a long secret, digest it first. 267 if (seclen > 64) { // 64: block size of HMAC-SHA1 268 sha.update(secret, off, seclen); 269 secKey = sha.digest(); 270 keyLen = secKey.length; 271 off = 0; 272 } 273 expand(sha, 20, secKey, off, keyLen, labelBytes, seed, output, 274 HMAC_ipad64.clone(), HMAC_opad64.clone()); 275 276 return output; 277 } 278 279 /* 280 * @param digest the MessageDigest to produce the HMAC 281 * @param hmacSize the HMAC size 282 * @param secret the secret 283 * @param secOff the offset into the secret 284 * @param secLen the secret length 285 * @param label the label 286 * @param seed the seed 287 * @param output the output array 288 */ expand(MessageDigest digest, int hmacSize, byte[] secret, int secOff, int secLen, byte[] label, byte[] seed, byte[] output, byte[] pad1, byte[] pad2)289 private static void expand(MessageDigest digest, int hmacSize, 290 byte[] secret, int secOff, int secLen, byte[] label, byte[] seed, 291 byte[] output, byte[] pad1, byte[] pad2) throws DigestException { 292 /* 293 * modify the padding used, by XORing the key into our copy of that 294 * padding. That's to avoid doing that for each HMAC computation. 295 */ 296 for (int i = 0; i < secLen; i++) { 297 pad1[i] ^= secret[i + secOff]; 298 pad2[i] ^= secret[i + secOff]; 299 } 300 301 byte[] tmp = new byte[hmacSize]; 302 byte[] aBytes = null; 303 304 /* 305 * compute: 306 * 307 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) + 308 * HMAC_hash(secret, A(2) + seed) + 309 * HMAC_hash(secret, A(3) + seed) + ... 310 * A() is defined as: 311 * 312 * A(0) = seed 313 * A(i) = HMAC_hash(secret, A(i-1)) 314 */ 315 int remaining = output.length; 316 int ofs = 0; 317 while (remaining > 0) { 318 /* 319 * compute A() ... 320 */ 321 // inner digest 322 digest.update(pad1); 323 if (aBytes == null) { 324 digest.update(label); 325 digest.update(seed); 326 } else { 327 digest.update(aBytes); 328 } 329 digest.digest(tmp, 0, hmacSize); 330 331 // outer digest 332 digest.update(pad2); 333 digest.update(tmp); 334 if (aBytes == null) { 335 aBytes = new byte[hmacSize]; 336 } 337 digest.digest(aBytes, 0, hmacSize); 338 339 /* 340 * compute HMAC_hash() ... 341 */ 342 // inner digest 343 digest.update(pad1); 344 digest.update(aBytes); 345 digest.update(label); 346 digest.update(seed); 347 digest.digest(tmp, 0, hmacSize); 348 349 // outer digest 350 digest.update(pad2); 351 digest.update(tmp); 352 digest.digest(tmp, 0, hmacSize); 353 354 int k = Math.min(hmacSize, remaining); 355 for (int i = 0; i < k; i++) { 356 output[ofs++] ^= tmp[i]; 357 } 358 remaining -= k; 359 } 360 } 361 362 /** 363 * A KeyGenerator implementation that supports TLS 1.2. 364 * <p> 365 * TLS 1.2 uses a different hash algorithm than 1.0/1.1 for the PRF 366 * calculations. As of 2010, there is no PKCS11-level support for TLS 367 * 1.2 PRF calculations, and no known OS's have an internal variant 368 * we could use. Therefore for TLS 1.2, we are updating JSSE to request 369 * a different provider algorithm: "SunTls12Prf". If we reused the 370 * name "SunTlsPrf", the PKCS11 provider would need be updated to 371 * fail correctly when presented with the wrong version number 372 * (via Provider.Service.supportsParameters()), and add the 373 * appropriate supportsParamters() checks into KeyGenerators (not 374 * currently there). 375 */ 376 public static class V12 extends TlsPrfGenerator { engineGenerateKey()377 protected SecretKey engineGenerateKey() { 378 return engineGenerateKey0(true); 379 } 380 } 381 382 /** 383 * A KeyGenerator implementation that supports TLS 1.0/1.1. 384 */ 385 public static class V10 extends TlsPrfGenerator { engineGenerateKey()386 protected SecretKey engineGenerateKey() { 387 return engineGenerateKey0(false); 388 } 389 } 390 } 391