1 /* 2 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved. 3 * Please refer to the LICENSE.txt for licensing details. 4 */ 5 package ch.ethz.ssh2.crypto; 6 7 import ch.ethz.ssh2.crypto.digest.HashForSSH2Types; 8 import java.math.BigInteger; 9 10 /** 11 * Establishes key material for iv/key/mac (both directions). 12 * 13 * @author Christian Plattner 14 * @version 2.50, 03/15/10 15 */ 16 public class KeyMaterial 17 { 18 public byte[] initial_iv_client_to_server; 19 public byte[] initial_iv_server_to_client; 20 public byte[] enc_key_client_to_server; 21 public byte[] enc_key_server_to_client; 22 public byte[] integrity_key_client_to_server; 23 public byte[] integrity_key_server_to_client; 24 calculateKey(HashForSSH2Types sh, BigInteger K, byte[] H, byte type, byte[] SessionID, int keyLength)25 private static byte[] calculateKey(HashForSSH2Types sh, BigInteger K, byte[] H, byte type, byte[] SessionID, 26 int keyLength) 27 { 28 byte[] res = new byte[keyLength]; 29 30 int dglen = sh.getDigestLength(); 31 int numRounds = (keyLength + dglen - 1) / dglen; 32 33 byte[][] tmp = new byte[numRounds][]; 34 35 sh.reset(); 36 sh.updateBigInt(K); 37 sh.updateBytes(H); 38 sh.updateByte(type); 39 sh.updateBytes(SessionID); 40 41 tmp[0] = sh.getDigest(); 42 43 int off = 0; 44 int produced = Math.min(dglen, keyLength); 45 46 System.arraycopy(tmp[0], 0, res, off, produced); 47 48 keyLength -= produced; 49 off += produced; 50 51 for (int i = 1; i < numRounds; i++) 52 { 53 sh.updateBigInt(K); 54 sh.updateBytes(H); 55 56 for (int j = 0; j < i; j++) 57 sh.updateBytes(tmp[j]); 58 59 tmp[i] = sh.getDigest(); 60 61 produced = Math.min(dglen, keyLength); 62 System.arraycopy(tmp[i], 0, res, off, produced); 63 keyLength -= produced; 64 off += produced; 65 } 66 67 return res; 68 } 69 create(String hashType, byte[] H, BigInteger K, byte[] SessionID, int keyLengthCS, int blockSizeCS, int macLengthCS, int keyLengthSC, int blockSizeSC, int macLengthSC)70 public static KeyMaterial create(String hashType, byte[] H, BigInteger K, byte[] SessionID, int keyLengthCS, 71 int blockSizeCS, int macLengthCS, int keyLengthSC, int blockSizeSC, int macLengthSC) 72 throws IllegalArgumentException 73 { 74 KeyMaterial km = new KeyMaterial(); 75 76 HashForSSH2Types sh = new HashForSSH2Types(hashType); 77 78 km.initial_iv_client_to_server = calculateKey(sh, K, H, (byte) 'A', SessionID, blockSizeCS); 79 80 km.initial_iv_server_to_client = calculateKey(sh, K, H, (byte) 'B', SessionID, blockSizeSC); 81 82 km.enc_key_client_to_server = calculateKey(sh, K, H, (byte) 'C', SessionID, keyLengthCS); 83 84 km.enc_key_server_to_client = calculateKey(sh, K, H, (byte) 'D', SessionID, keyLengthSC); 85 86 km.integrity_key_client_to_server = calculateKey(sh, K, H, (byte) 'E', SessionID, macLengthCS); 87 88 km.integrity_key_server_to_client = calculateKey(sh, K, H, (byte) 'F', SessionID, macLengthSC); 89 90 return km; 91 } 92 } 93