github.com/pion/dtls/v2@v2.2.12/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go (about)

     1  // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
     2  // SPDX-License-Identifier: MIT
     3  
     4  package ciphersuite
     5  
     6  import (
     7  	"crypto/sha256"
     8  	"fmt"
     9  	"hash"
    10  	"sync/atomic"
    11  
    12  	"github.com/pion/dtls/v2/pkg/crypto/ciphersuite"
    13  	"github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
    14  	"github.com/pion/dtls/v2/pkg/crypto/prf"
    15  	"github.com/pion/dtls/v2/pkg/protocol/recordlayer"
    16  )
    17  
    18  // TLSEcdheEcdsaWithAes128GcmSha256  represents a TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 CipherSuite
    19  type TLSEcdheEcdsaWithAes128GcmSha256 struct {
    20  	gcm atomic.Value // *cryptoGCM
    21  }
    22  
    23  // CertificateType returns what type of certficate this CipherSuite exchanges
    24  func (c *TLSEcdheEcdsaWithAes128GcmSha256) CertificateType() clientcertificate.Type {
    25  	return clientcertificate.ECDSASign
    26  }
    27  
    28  // KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake
    29  func (c *TLSEcdheEcdsaWithAes128GcmSha256) KeyExchangeAlgorithm() KeyExchangeAlgorithm {
    30  	return KeyExchangeAlgorithmEcdhe
    31  }
    32  
    33  // ECC uses Elliptic Curve Cryptography
    34  func (c *TLSEcdheEcdsaWithAes128GcmSha256) ECC() bool {
    35  	return true
    36  }
    37  
    38  // ID returns the ID of the CipherSuite
    39  func (c *TLSEcdheEcdsaWithAes128GcmSha256) ID() ID {
    40  	return TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    41  }
    42  
    43  func (c *TLSEcdheEcdsaWithAes128GcmSha256) String() string {
    44  	return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
    45  }
    46  
    47  // HashFunc returns the hashing func for this CipherSuite
    48  func (c *TLSEcdheEcdsaWithAes128GcmSha256) HashFunc() func() hash.Hash {
    49  	return sha256.New
    50  }
    51  
    52  // AuthenticationType controls what authentication method is using during the handshake
    53  func (c *TLSEcdheEcdsaWithAes128GcmSha256) AuthenticationType() AuthenticationType {
    54  	return AuthenticationTypeCertificate
    55  }
    56  
    57  // IsInitialized returns if the CipherSuite has keying material and can
    58  // encrypt/decrypt packets
    59  func (c *TLSEcdheEcdsaWithAes128GcmSha256) IsInitialized() bool {
    60  	return c.gcm.Load() != nil
    61  }
    62  
    63  func (c *TLSEcdheEcdsaWithAes128GcmSha256) init(masterSecret, clientRandom, serverRandom []byte, isClient bool, prfMacLen, prfKeyLen, prfIvLen int, hashFunc func() hash.Hash) error {
    64  	keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, hashFunc)
    65  	if err != nil {
    66  		return err
    67  	}
    68  
    69  	var gcm *ciphersuite.GCM
    70  	if isClient {
    71  		gcm, err = ciphersuite.NewGCM(keys.ClientWriteKey, keys.ClientWriteIV, keys.ServerWriteKey, keys.ServerWriteIV)
    72  	} else {
    73  		gcm, err = ciphersuite.NewGCM(keys.ServerWriteKey, keys.ServerWriteIV, keys.ClientWriteKey, keys.ClientWriteIV)
    74  	}
    75  	c.gcm.Store(gcm)
    76  	return err
    77  }
    78  
    79  // Init initializes the internal Cipher with keying material
    80  func (c *TLSEcdheEcdsaWithAes128GcmSha256) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error {
    81  	const (
    82  		prfMacLen = 0
    83  		prfKeyLen = 16
    84  		prfIvLen  = 4
    85  	)
    86  
    87  	return c.init(masterSecret, clientRandom, serverRandom, isClient, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc())
    88  }
    89  
    90  // Encrypt encrypts a single TLS RecordLayer
    91  func (c *TLSEcdheEcdsaWithAes128GcmSha256) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) {
    92  	cipherSuite, ok := c.gcm.Load().(*ciphersuite.GCM)
    93  	if !ok {
    94  		return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit)
    95  	}
    96  
    97  	return cipherSuite.Encrypt(pkt, raw)
    98  }
    99  
   100  // Decrypt decrypts a single TLS RecordLayer
   101  func (c *TLSEcdheEcdsaWithAes128GcmSha256) Decrypt(raw []byte) ([]byte, error) {
   102  	cipherSuite, ok := c.gcm.Load().(*ciphersuite.GCM)
   103  	if !ok {
   104  		return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit)
   105  	}
   106  
   107  	return cipherSuite.Decrypt(raw)
   108  }