You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							138 lines
						
					
					
						
							3.0 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							138 lines
						
					
					
						
							3.0 KiB
						
					
					
				
								package coscrypto
							 | 
						|
								
							 | 
						|
								import (
							 | 
						|
									"io"
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								const (
							 | 
						|
									aesKeySize = 32
							 | 
						|
									ivSize     = 16
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								type aesCtrCipherBuilder struct {
							 | 
						|
									MasterCipher MasterCipher
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								type aesCtrCipher struct {
							 | 
						|
									CipherData CipherData
							 | 
						|
									Cipher     Cipher
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func CreateAesCtrBuilder(cipher MasterCipher) ContentCipherBuilder {
							 | 
						|
									return aesCtrCipherBuilder{MasterCipher: cipher}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (builder aesCtrCipherBuilder) createCipherData() (CipherData, error) {
							 | 
						|
									var cd CipherData
							 | 
						|
									var err error
							 | 
						|
									err = cd.RandomKeyIv(aesKeySize, ivSize)
							 | 
						|
									if err != nil {
							 | 
						|
										return cd, err
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									cd.WrapAlgorithm = builder.MasterCipher.GetWrapAlgorithm()
							 | 
						|
									cd.CEKAlgorithm = AesCtrAlgorithm
							 | 
						|
									cd.MatDesc = builder.MasterCipher.GetMatDesc()
							 | 
						|
								
							 | 
						|
									// EncryptedKey
							 | 
						|
									cd.EncryptedKey, err = builder.MasterCipher.Encrypt(cd.Key)
							 | 
						|
									if err != nil {
							 | 
						|
										return cd, err
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// EncryptedIV
							 | 
						|
									cd.EncryptedIV, err = builder.MasterCipher.Encrypt(cd.IV)
							 | 
						|
									if err != nil {
							 | 
						|
										return cd, err
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									return cd, nil
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (builder aesCtrCipherBuilder) contentCipherCD(cd CipherData) (ContentCipher, error) {
							 | 
						|
									cipher, err := newAesCtr(cd)
							 | 
						|
									if err != nil {
							 | 
						|
										return nil, err
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									return &aesCtrCipher{
							 | 
						|
										CipherData: cd,
							 | 
						|
										Cipher:     cipher,
							 | 
						|
									}, nil
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (builder aesCtrCipherBuilder) ContentCipher() (ContentCipher, error) {
							 | 
						|
									cd, err := builder.createCipherData()
							 | 
						|
									if err != nil {
							 | 
						|
										return nil, err
							 | 
						|
									}
							 | 
						|
									return builder.contentCipherCD(cd)
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (builder aesCtrCipherBuilder) ContentCipherEnv(envelope Envelope) (ContentCipher, error) {
							 | 
						|
									var cd CipherData
							 | 
						|
									cd.EncryptedKey = make([]byte, len(envelope.CipherKey))
							 | 
						|
									copy(cd.EncryptedKey, []byte(envelope.CipherKey))
							 | 
						|
								
							 | 
						|
									plainKey, err := builder.MasterCipher.Decrypt([]byte(envelope.CipherKey))
							 | 
						|
									if err != nil {
							 | 
						|
										return nil, err
							 | 
						|
									}
							 | 
						|
									cd.Key = make([]byte, len(plainKey))
							 | 
						|
									copy(cd.Key, plainKey)
							 | 
						|
								
							 | 
						|
									cd.EncryptedIV = make([]byte, len(envelope.IV))
							 | 
						|
									copy(cd.EncryptedIV, []byte(envelope.IV))
							 | 
						|
								
							 | 
						|
									plainIV, err := builder.MasterCipher.Decrypt([]byte(envelope.IV))
							 | 
						|
									if err != nil {
							 | 
						|
										return nil, err
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									cd.IV = make([]byte, len(plainIV))
							 | 
						|
									copy(cd.IV, plainIV)
							 | 
						|
								
							 | 
						|
									cd.MatDesc = envelope.MatDesc
							 | 
						|
									cd.WrapAlgorithm = envelope.WrapAlg
							 | 
						|
									cd.CEKAlgorithm = envelope.CEKAlg
							 | 
						|
								
							 | 
						|
									return builder.contentCipherCD(cd)
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (builder aesCtrCipherBuilder) GetMatDesc() string {
							 | 
						|
									return builder.MasterCipher.GetMatDesc()
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (cc *aesCtrCipher) EncryptContent(src io.Reader) (io.ReadCloser, error) {
							 | 
						|
									reader := cc.Cipher.Encrypt(src)
							 | 
						|
									return &CryptoEncrypter{Body: src, Encrypter: reader}, nil
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (cc *aesCtrCipher) DecryptContent(src io.Reader) (io.ReadCloser, error) {
							 | 
						|
									reader := cc.Cipher.Decrypt(src)
							 | 
						|
									return &CryptoDecrypter{Body: src, Decrypter: reader}, nil
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (cc *aesCtrCipher) GetCipherData() *CipherData {
							 | 
						|
									return &(cc.CipherData)
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (cc *aesCtrCipher) GetEncryptedLen(plainTextLen int64) int64 {
							 | 
						|
									return plainTextLen
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (cc *aesCtrCipher) GetAlignLen() int {
							 | 
						|
									return len(cc.CipherData.IV)
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (cc *aesCtrCipher) Clone(cd CipherData) (ContentCipher, error) {
							 | 
						|
									cipher, err := newAesCtr(cd)
							 | 
						|
									if err != nil {
							 | 
						|
										return nil, err
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									return &aesCtrCipher{
							 | 
						|
										CipherData: cd,
							 | 
						|
										Cipher:     cipher,
							 | 
						|
									}, nil
							 | 
						|
								}
							 |