• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16 
17 package com.google.crypto.tink.subtle;
18 
19 import com.google.crypto.tink.util.Bytes;
20 import java.security.GeneralSecurityException;
21 import java.security.KeyPair;
22 import java.security.interfaces.ECPrivateKey;
23 import java.security.interfaces.ECPublicKey;
24 
25 /**
26  * HKDF-based ECIES-KEM (key encapsulation mechanism) for ECIES sender.
27  *
28  * @since 1.0.0
29  */
30 public final class EciesHkdfSenderKem {
31   private final ECPublicKey recipientPublicKey;
32 
33   /** A container for key parts generated by the KEM. */
34   public static final class KemKey {
35     private final Bytes kemBytes;
36     private final Bytes symmetricKey;
37 
KemKey(final byte[] kemBytes, final byte[] symmetricKey)38     public KemKey(final byte[] kemBytes, final byte[] symmetricKey) {
39       if (kemBytes == null) {
40         throw new NullPointerException("KemBytes must be non-null");
41       }
42       if (symmetricKey == null) {
43         throw new NullPointerException("symmetricKey must be non-null");
44       }
45       this.kemBytes = Bytes.copyFrom(kemBytes);
46       this.symmetricKey = Bytes.copyFrom(symmetricKey);
47     }
48 
getKemBytes()49     public byte[] getKemBytes() {
50       return kemBytes.toByteArray();
51     }
52 
getSymmetricKey()53     public byte[] getSymmetricKey() {
54       return symmetricKey.toByteArray();
55     }
56   }
57 
EciesHkdfSenderKem(final ECPublicKey recipientPublicKey)58   public EciesHkdfSenderKem(final ECPublicKey recipientPublicKey) {
59     this.recipientPublicKey = recipientPublicKey;
60   }
61 
generateKey( String hmacAlgo, final byte[] hkdfSalt, final byte[] hkdfInfo, int keySizeInBytes, EllipticCurves.PointFormatType pointFormat)62   public KemKey generateKey(
63       String hmacAlgo,
64       final byte[] hkdfSalt,
65       final byte[] hkdfInfo,
66       int keySizeInBytes,
67       EllipticCurves.PointFormatType pointFormat)
68       throws GeneralSecurityException {
69     KeyPair ephemeralKeyPair = EllipticCurves.generateKeyPair(recipientPublicKey.getParams());
70     ECPublicKey ephemeralPublicKey = (ECPublicKey) ephemeralKeyPair.getPublic();
71     ECPrivateKey ephemeralPrivateKey = (ECPrivateKey) ephemeralKeyPair.getPrivate();
72     byte[] sharedSecret = EllipticCurves.computeSharedSecret(
73         ephemeralPrivateKey, recipientPublicKey);
74     byte[] kemBytes =
75         EllipticCurves.pointEncode(
76             ephemeralPublicKey.getParams().getCurve(), pointFormat, ephemeralPublicKey.getW());
77     byte[] symmetricKey =
78         Hkdf.computeEciesHkdfSymmetricKey(
79             kemBytes, sharedSecret, hmacAlgo, hkdfSalt, hkdfInfo, keySizeInBytes);
80     return new KemKey(kemBytes, symmetricKey);
81   }
82 }
83