OpenSSLMac.java revision 0d4ee1f9b8c37fb33cd74da4efac5905ba138e45
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package org.apache.harmony.xnet.provider.jsse; 18 19import java.security.InvalidAlgorithmParameterException; 20import java.security.InvalidKeyException; 21import java.security.Key; 22import java.security.NoSuchAlgorithmException; 23import java.security.spec.AlgorithmParameterSpec; 24 25import javax.crypto.MacSpi; 26import javax.crypto.SecretKey; 27 28public abstract class OpenSSLMac extends MacSpi { 29 private final OpenSSLDigestContext ctx = new OpenSSLDigestContext( 30 NativeCrypto.EVP_MD_CTX_create()); 31 32 /** 33 * Holds the EVP_MD for the hashing algorithm, e.g. 34 * EVP_get_digestbyname("sha1"); 35 */ 36 private final int evp_md; 37 38 /** 39 * The key type of the secret key. 40 */ 41 private final int evp_pkey_type; 42 43 /** 44 * The secret key used in this keyed MAC. 45 */ 46 private OpenSSLKey macKey; 47 48 /** 49 * Holds the output size of the message digest. 50 */ 51 private final int size; 52 53 /** 54 * Holds a dummy buffer for writing single bytes to the digest. 55 */ 56 private final byte[] singleByte = new byte[1]; 57 58 protected OpenSSLMac(int evp_md, int size, int evp_pkey_type) { 59 this.evp_md = evp_md; 60 this.size = size; 61 this.evp_pkey_type = evp_pkey_type; 62 } 63 64 @Override 65 protected int engineGetMacLength() { 66 return size; 67 } 68 69 @Override 70 protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, 71 InvalidAlgorithmParameterException { 72 if (!(key instanceof SecretKey)) { 73 throw new InvalidKeyException("key must be a SecretKey"); 74 } 75 76 if (params != null) { 77 throw new InvalidAlgorithmParameterException("unknown parameter type"); 78 } 79 80 final byte[] keyBytes = key.getEncoded(); 81 if (keyBytes == null) { 82 throw new InvalidKeyException("key cannot be encoded"); 83 } 84 85 NativeCrypto.EVP_MD_CTX_init(ctx.getContext()); 86 macKey = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_mac_key(evp_pkey_type, keyBytes)); 87 88 reset(); 89 } 90 91 private void reset() { 92 NativeCrypto.EVP_DigestSignInit(ctx.getContext(), evp_md, macKey.getPkeyContext()); 93 } 94 95 @Override 96 protected void engineUpdate(byte input) { 97 singleByte[0] = input; 98 engineUpdate(singleByte, 0, 1); 99 } 100 101 @Override 102 protected void engineUpdate(byte[] input, int offset, int len) { 103 NativeCrypto.EVP_DigestUpdate(ctx.getContext(), input, offset, len); 104 } 105 106 @Override 107 protected byte[] engineDoFinal() { 108 final byte[] output = NativeCrypto.EVP_DigestSignFinal(ctx.getContext()); 109 reset(); 110 return output; 111 } 112 113 @Override 114 protected void engineReset() { 115 reset(); 116 } 117 118 public static class HmacMD5 extends OpenSSLMac { 119 private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("md5"); 120 private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); 121 122 public HmacMD5() { 123 super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC); 124 } 125 } 126 127 public static class HmacSHA1 extends OpenSSLMac { 128 private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1"); 129 private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); 130 131 public HmacSHA1() { 132 super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC); 133 } 134 } 135 136 public static class HmacSHA256 extends OpenSSLMac { 137 private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256"); 138 private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); 139 140 public HmacSHA256() throws NoSuchAlgorithmException { 141 super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC); 142 } 143 } 144 145 public static class HmacSHA384 extends OpenSSLMac { 146 private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384"); 147 private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); 148 149 public HmacSHA384() throws NoSuchAlgorithmException { 150 super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC); 151 } 152 } 153 154 public static class HmacSHA512 extends OpenSSLMac { 155 private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512"); 156 private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); 157 158 public HmacSHA512() { 159 super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC); 160 } 161 } 162} 163