group_crypto.mx raw

   1  package mls
   2  
   3  // MLS group crypto operations (RFC 9420 §11, §12).
   4  // GroupInfo signing, Welcome encryption/decryption.
   5  
   6  import "errors"
   7  
   8  var (
   9  	errGroupSecretsNotFound = errors.New("mls: group secrets not found for key package ref")
  10  )
  11  
  12  func (info *groupInfo) verifySignature(signerPub signaturePublicKey) bool {
  13  	cs := info.groupContext.cipherSuite
  14  	var w Writer
  15  	info.marshalTBS(&w)
  16  	tbs, err := w.bytes()
  17  	if err != nil {
  18  		return false
  19  	}
  20  	return cs.verifyWithLabel(signerPub, []byte("GroupInfoTBS"), tbs, info.signature)
  21  }
  22  
  23  func (info *groupInfo) sign(signerPriv signaturePrivateKey) error {
  24  	cs := info.groupContext.cipherSuite
  25  	var w Writer
  26  	info.marshalTBS(&w)
  27  	tbs, err := w.bytes()
  28  	if err != nil {
  29  		return err
  30  	}
  31  	sig, err := cs.signWithLabel(signerPriv, []byte("GroupInfoTBS"), tbs)
  32  	if err != nil {
  33  		return err
  34  	}
  35  	info.signature = sig
  36  	return nil
  37  }
  38  
  39  func (info *groupInfo) verifyConfirmationTag(joinerSecret, pskSecret []byte) bool {
  40  	cs := info.groupContext.cipherSuite
  41  	epochSecret, err := info.groupContext.extractEpochSecret(joinerSecret, pskSecret)
  42  	if err != nil {
  43  		return false
  44  	}
  45  	confirmationKey, err := cs.deriveSecret(epochSecret, secretLabelConfirm)
  46  	if err != nil {
  47  		return false
  48  	}
  49  	return cs.verifyMAC(confirmationKey, info.groupContext.confirmedTranscriptHash, info.confirmationTag)
  50  }
  51  
  52  func (info *groupInfo) encrypt(joinerSecret, pskSecret []byte) ([]byte, error) {
  53  	cs := info.groupContext.cipherSuite
  54  	welcomeSecret, err := extractWelcomeSecret(cs, joinerSecret, pskSecret)
  55  	if err != nil {
  56  		return nil, err
  57  	}
  58  
  59  	welcomeNonce, err := cs.expandWithLabel(welcomeSecret, []byte("nonce"), nil, uint16(cs.AEADNonceSize()))
  60  	if err != nil {
  61  		return nil, err
  62  	}
  63  	welcomeKey, err := cs.expandWithLabel(welcomeSecret, []byte("key"), nil, uint16(cs.AEADKeySize()))
  64  	if err != nil {
  65  		return nil, err
  66  	}
  67  
  68  	rawGroupInfo, err := marshalRaw(info)
  69  	if err != nil {
  70  		return nil, err
  71  	}
  72  
  73  	return cs.aeadSeal(welcomeKey, welcomeNonce, rawGroupInfo, nil)
  74  }
  75  
  76  func (sec *groupSecrets) encrypt(cs CipherSuite, initKey hpkePublicKey, encryptedGroupInfo []byte) (*hpkeCiphertext, error) {
  77  	raw, err := marshalRaw(sec)
  78  	if err != nil {
  79  		return nil, err
  80  	}
  81  	kemOutput, ciphertext, err := cs.encryptWithLabel(initKey, []byte("Welcome"), encryptedGroupInfo, raw)
  82  	if err != nil {
  83  		return nil, err
  84  	}
  85  	return &hpkeCiphertext{kemOutput: kemOutput, ciphertext: ciphertext}, nil
  86  }
  87  
  88  func (w *Welcome) decryptGroupSecrets(ref KeyPackageRef, initKeyPriv hpkePrivateKey) (*groupSecrets, error) {
  89  	cs := w.cipherSuite
  90  	sec := w.findSecret(ref)
  91  	if sec == nil {
  92  		return nil, errGroupSecretsNotFound
  93  	}
  94  	raw, err := cs.decryptWithLabel(initKeyPriv, []byte("Welcome"), w.encryptedGroupInfo, sec.encryptedGroupSecrets.kemOutput, sec.encryptedGroupSecrets.ciphertext)
  95  	if err != nil {
  96  		return nil, err
  97  	}
  98  	var gs groupSecrets
  99  	if err := unmarshalRaw(raw, &gs); err != nil {
 100  		return nil, err
 101  	}
 102  	return &gs, nil
 103  }
 104  
 105  func (w *Welcome) decryptGroupInfo(joinerSecret, pskSecret []byte) (*groupInfo, error) {
 106  	cs := w.cipherSuite
 107  	welcomeSecret, err := extractWelcomeSecret(cs, joinerSecret, pskSecret)
 108  	if err != nil {
 109  		return nil, err
 110  	}
 111  
 112  	welcomeNonce, err := cs.expandWithLabel(welcomeSecret, []byte("nonce"), nil, uint16(cs.AEADNonceSize()))
 113  	if err != nil {
 114  		return nil, err
 115  	}
 116  	welcomeKey, err := cs.expandWithLabel(welcomeSecret, []byte("key"), nil, uint16(cs.AEADKeySize()))
 117  	if err != nil {
 118  		return nil, err
 119  	}
 120  
 121  	rawGroupInfo, err := cs.aeadOpen(welcomeKey, welcomeNonce, w.encryptedGroupInfo, nil)
 122  	if err != nil {
 123  		return nil, err
 124  	}
 125  
 126  	var info groupInfo
 127  	if err := unmarshalRaw(rawGroupInfo, &info); err != nil {
 128  		return nil, err
 129  	}
 130  	return &info, nil
 131  }
 132