@@ -10,7 +10,7 @@ import {
1010} from '../platform'
1111import { _asnhex_getHexOfV_AtObj , _asnhex_getPosArrayOfChildren_AtObj } from "./asn1hex" ;
1212import { RSAKey } from "./rsa" ;
13- import { getKeeperKeys } from "../transmissionKeys" ;
13+ import { getKeeperKeys , getKeeperMlKemKeys } from "../transmissionKeys" ;
1414import { normal64 , normal64Bytes , webSafe64FromBytes } from "../utils" ;
1515import { SocketProxy , socketSendMessage } from '../socket'
1616import * as asmCrypto from 'asmcrypto.js'
@@ -45,6 +45,7 @@ export const browserPlatform: Platform = class {
4545 }
4646
4747 static keys = getKeeperKeys ( this . normal64Bytes ) ;
48+ static mlKemKeys = getKeeperMlKemKeys ( this . base64ToBytes ) ;
4849
4950 static getRandomBytes ( length : number ) : Uint8Array {
5051 let data = new Uint8Array ( length ) ;
@@ -540,6 +541,27 @@ export const browserPlatform: Platform = class {
540541 return await crypto . subtle . importKey ( 'jwk' , jwk , { name : 'ECDH' , namedCurve : 'P-256' } , true , [ 'deriveBits' ] )
541542 }
542543
544+ static async ecdhComputeSharedSecret (
545+ senderPrivateKey : Uint8Array ,
546+ recipientPublicKey : Uint8Array ,
547+ senderPublicKey : Uint8Array
548+ ) : Promise < Uint8Array > {
549+ const senderPrivateCryptoKey = await this . importPrivateKeyEC ( senderPrivateKey , senderPublicKey )
550+ const recipientPublicCryptoKey = await crypto . subtle . importKey (
551+ 'raw' ,
552+ recipientPublicKey ,
553+ { name : 'ECDH' , namedCurve : 'P-256' } ,
554+ false ,
555+ [ ]
556+ )
557+ const sharedSecretBuffer = await crypto . subtle . deriveBits (
558+ { name : 'ECDH' , public : recipientPublicCryptoKey } ,
559+ senderPrivateCryptoKey ,
560+ 256
561+ )
562+ return new Uint8Array ( sharedSecretBuffer )
563+ }
564+
543565 static async deriveSharedSecretKey ( ephemeralPublicKey : Uint8Array , privateKey : CryptoKey , id ?: Uint8Array , useHKDF ?: boolean ) : Promise < CryptoKey > {
544566 const pubCryptoKey = await crypto . subtle . importKey ( 'raw' , ephemeralPublicKey , { name : 'ECDH' , namedCurve : 'P-256' } , true , [ ] )
545567 const sharedSecret = await crypto . subtle . deriveBits ( { name : 'ECDH' , public : pubCryptoKey } , privateKey , 256 )
@@ -552,28 +574,36 @@ export const browserPlatform: Platform = class {
552574 const symmetricKeyBuffer = await crypto . subtle . digest ( 'SHA-256' , sharedSecretCombined )
553575 return this . aesGcmImportKey ( new Uint8Array ( symmetricKeyBuffer ) , false )
554576 } else {
555- const hkdfKey = await crypto . subtle . importKey (
556- 'raw' ,
557- sharedSecret ,
558- 'HKDF' ,
559- false ,
560- [ 'deriveBits' ]
561- )
562-
563- const symmetricKeyBuffer = await crypto . subtle . deriveBits (
564- {
565- name : 'HKDF' ,
566- hash : 'SHA-256' ,
567- salt : new Uint8Array ( ) ,
568- info : id ?? new Uint8Array ( )
569- } ,
570- hkdfKey ,
571- 256
572- )
573- return this . aesGcmImportKey ( new Uint8Array ( symmetricKeyBuffer ) , false )
577+ const symmetricKey = await this . hkdf ( new Uint8Array ( ) , new Uint8Array ( sharedSecret ) , id ?? new Uint8Array ( ) , 32 )
578+ return this . aesGcmImportKey ( symmetricKey , false )
574579 }
575580 }
576581
582+ static async hkdf ( salt : Uint8Array , ikm : Uint8Array , info : Uint8Array , length : number ) : Promise < Uint8Array > {
583+ // Import IKM as HKDF key
584+ const hkdfKey = await crypto . subtle . importKey (
585+ 'raw' ,
586+ ikm ,
587+ 'HKDF' ,
588+ false ,
589+ [ 'deriveBits' ]
590+ ) ;
591+
592+ // Derive bits using HKDF
593+ const derivedBits = await crypto . subtle . deriveBits (
594+ {
595+ name : 'HKDF' ,
596+ hash : 'SHA-256' ,
597+ salt : salt ,
598+ info : info
599+ } ,
600+ hkdfKey ,
601+ length * 8 // bits
602+ ) ;
603+
604+ return new Uint8Array ( derivedBits ) ;
605+ }
606+
577607 static async privateDecryptECWebCrypto ( data : Uint8Array , privateKey : CryptoKey , id ?: Uint8Array , useHKDF ?: boolean ) : Promise < Uint8Array > {
578608 const message = data . slice ( ECC_PUB_KEY_LENGTH )
579609 const ephemeralPublicKey = data . slice ( 0 , ECC_PUB_KEY_LENGTH )
@@ -808,7 +838,11 @@ export const browserPlatform: Platform = class {
808838 }
809839
810840 static async calcAuthVerifier ( key : Uint8Array ) : Promise < Uint8Array > {
811- let digest = await crypto . subtle . digest ( "SHA-256" , key ) ;
841+ return this . sha256 ( key ) ;
842+ }
843+
844+ static async sha256 ( data : Uint8Array ) : Promise < Uint8Array > {
845+ const digest = await crypto . subtle . digest ( "SHA-256" , data ) ;
812846 return new Uint8Array ( digest ) ;
813847 }
814848
0 commit comments