/* * Copyright 2018 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. * */ package com.google.webauthn.gaedemo.objects; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.security.KeyPair; import java.security.interfaces.ECPublicKey; import org.bouncycastle.util.Arrays; import com.google.common.primitives.Bytes; import com.google.webauthn.gaedemo.crypto.Crypto; public class CablePairingData { public int version; public byte[] irk; public byte[] lk; private static int HKDF_SHA_LENGTH = 64; private static int K_LENGTH = 32; public CablePairingData(int version, byte[] irk, byte[] lk) { this.version = version; this.irk = irk; this.lk = lk; } public CablePairingData() {} /** * @param cableData * @param sessionKeyPair * @return */ public static CablePairingData generatePairingData(CableRegistrationData cableData, KeyPair sessionKeyPair) { byte[] sharedSecret = Crypto.getS(sessionKeyPair.getPrivate(), cableData.publicKey); byte[] info = "FIDO caBLE v1 pairing data".getBytes(StandardCharsets.US_ASCII); byte[] version = ByteBuffer.allocate(4).putInt(cableData.versions.get(0)).array(); byte[] result = Crypto.hkdfSha256(sharedSecret, Crypto.sha256Digest(Bytes.concat(version, Crypto.compressECPublicKey((ECPublicKey) sessionKeyPair.getPublic()), cableData.publicKey)), info, HKDF_SHA_LENGTH); return new CablePairingData(cableData.versions.get(0), Arrays.copyOf(result, K_LENGTH), Arrays.copyOfRange(result, K_LENGTH, 2 * K_LENGTH)); } }