comparison src/com/trilead/ssh2/crypto/digest/MAC.java @ 0:0ce5cc452d02

initial version
author Carl Byington <carl@five-ten-sg.com>
date Thu, 22 May 2014 10:41:19 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:0ce5cc452d02
1
2 package com.trilead.ssh2.crypto.digest;
3
4 import java.security.InvalidKeyException;
5 import java.security.NoSuchAlgorithmException;
6
7 import javax.crypto.Mac;
8 import javax.crypto.ShortBufferException;
9 import javax.crypto.spec.SecretKeySpec;
10
11 /**
12 * MAC.
13 *
14 * @author Christian Plattner, plattner@trilead.com
15 * @version $Id: MAC.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
16 */
17 public final class MAC {
18 /**
19 * From http://tools.ietf.org/html/rfc4253
20 */
21 private static final String HMAC_MD5 = "hmac-md5";
22
23 /**
24 * From http://tools.ietf.org/html/rfc4253
25 */
26 private static final String HMAC_MD5_96 = "hmac-md5-96";
27
28 /**
29 * From http://tools.ietf.org/html/rfc4253
30 */
31 private static final String HMAC_SHA1 = "hmac-sha1";
32
33 /**
34 * From http://tools.ietf.org/html/rfc4253
35 */
36 private static final String HMAC_SHA1_96 = "hmac-sha1-96";
37
38 /**
39 * From http://tools.ietf.org/html/rfc6668
40 */
41 private static final String HMAC_SHA2_256 = "hmac-sha2-256";
42
43 /**
44 * From http://tools.ietf.org/html/rfc6668
45 */
46 private static final String HMAC_SHA2_512 = "hmac-sha2-512";
47
48 Mac mac;
49 int outSize;
50 int macSize;
51 byte[] buffer;
52
53 /* Higher Priority First */
54 private static final String[] MAC_LIST = {
55 HMAC_SHA2_256, HMAC_SHA2_512,
56 HMAC_SHA1_96, HMAC_SHA1, HMAC_MD5_96, HMAC_MD5
57 };
58
59 public final static String[] getMacList() {
60 return MAC_LIST;
61 }
62
63 public final static void checkMacList(String[] macs) {
64 for (int i = 0; i < macs.length; i++)
65 getKeyLen(macs[i]);
66 }
67
68 public final static int getKeyLen(String type) {
69 if (HMAC_SHA1.equals(type) || HMAC_SHA1_96.equals(type))
70 return 20;
71
72 if (HMAC_MD5.equals(type) || HMAC_MD5_96.equals(type))
73 return 16;
74
75 if (HMAC_SHA2_256.equals(type))
76 return 32;
77
78 if (HMAC_SHA2_512.equals(type))
79 return 64;
80
81 throw new IllegalArgumentException("Unkown algorithm " + type);
82 }
83
84 public MAC(String type, byte[] key) {
85 try {
86 if (HMAC_SHA1.equals(type) || HMAC_SHA1_96.equals(type)) {
87 mac = Mac.getInstance("HmacSHA1");
88 }
89 else if (HMAC_MD5.equals(type) || HMAC_MD5_96.equals(type)) {
90 mac = Mac.getInstance("HmacMD5");
91 }
92 else if (HMAC_SHA2_256.equals(type)) {
93 mac = Mac.getInstance("HmacSHA256");
94 }
95 else if (HMAC_SHA2_512.equals(type)) {
96 mac = Mac.getInstance("HmacSHA512");
97 }
98 else
99 throw new IllegalArgumentException("Unkown algorithm " + type);
100 }
101 catch (NoSuchAlgorithmException e) {
102 throw new IllegalArgumentException("Unknown algorithm " + type, e);
103 }
104
105 macSize = mac.getMacLength();
106
107 if (type.endsWith("-96")) {
108 outSize = 12;
109 buffer = new byte[macSize];
110 }
111 else {
112 outSize = macSize;
113 buffer = null;
114 }
115
116 try {
117 mac.init(new SecretKeySpec(key, type));
118 }
119 catch (InvalidKeyException e) {
120 throw new IllegalArgumentException(e);
121 }
122 }
123
124 public final void initMac(int seq) {
125 mac.reset();
126 mac.update((byte)(seq >> 24));
127 mac.update((byte)(seq >> 16));
128 mac.update((byte)(seq >> 8));
129 mac.update((byte)(seq));
130 }
131
132 public final void update(byte[] packetdata, int off, int len) {
133 mac.update(packetdata, off, len);
134 }
135
136 public final void getMac(byte[] out, int off) {
137 try {
138 if (buffer != null) {
139 mac.doFinal(buffer, 0);
140 System.arraycopy(buffer, 0, out, off, out.length - off);
141 }
142 else {
143 mac.doFinal(out, off);
144 }
145 }
146 catch (ShortBufferException e) {
147 throw new IllegalStateException(e);
148 }
149 }
150
151 public final int size() {
152 return outSize;
153 }
154 }