okay, aes done for real this time.
This commit is contained in:
		
							parent
							
								
									0203f8b0d8
								
							
						
					
					
						commit
						234de69be2
					
				
							
								
								
									
										10
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								TODO
									
									
									
									
									
								
							| @ -1,12 +1,20 @@ | ||||
| - keytypes | ||||
| 
 | ||||
| -- dsa, ecdsa, ecdsa-sk, ed25519, ed25519-sk, rsa ("-sk" variant is FIDO key) | ||||
| 
 | ||||
| -- if rsa, signature types: | ||||
| 
 | ||||
| --- ssh-rsa (sha1), rsa-sha2-256, rsa-sha2-512 (new default) | ||||
| 
 | ||||
| 
 | ||||
| - ciphers: | ||||
| -- 3des-cbc, aes128-cbc, aes192-cbc, aes256-cbc, aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, aes256-gcm@openssh.com, chacha20-poly1305@openssh.com | ||||
| 
 | ||||
| -- finish trimming copypasta for aes. | ||||
|    we COULD have a unified AllocateEncrypt and AllocatedDecrypt for AesCipher, but that'd require a func argument for encryption/decryption - which means | ||||
|    we COULD have a unified AllocateEncrypt and AllocatedDecrypt for AesCipher, but that'd require a func argument for encryption/decryption - which means breakage. | ||||
| 
 | ||||
| -- test AES GCM? | ||||
|    (and other unit tests) | ||||
| 
 | ||||
| provide marshal, unmarshal for keytypes/* keys. | ||||
| https://golangexample.com/encode-and-decode-binary-message-and-file-formats-in-go/ (?) | ||||
|  | ||||
| @ -734,7 +734,7 @@ pre.rouge { | ||||
| <h1>OpenSSH Key Structure Guide</h1> | ||||
| <div class="details"> | ||||
| <span id="author" class="author">brent saner <bts@square-r00t.net>, https://r00t2.io</span><br> | ||||
| <span id="revdate">Last updated 2022-04-29 02:49:33 -0400</span> | ||||
| <span id="revdate">Last updated 2022-04-29 04:09:49 -0400</span> | ||||
| </div> | ||||
| <div id="toc" class="toc2"> | ||||
| <div id="toctitle">Table of Contents</div> | ||||
|  | ||||
| @ -1,10 +0,0 @@ | ||||
| package aes128 | ||||
| 
 | ||||
| import ( | ||||
| 	sshAES `r00t2.io/sshkeys/cipher/aes` | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	KeySize    int = 16 // in bytes; AES128 is so named for its 128-bit key, thus: 128 / 8 = 16 | ||||
| 	KdfKeySize int = KeySize + sshAES.IvSize | ||||
| ) | ||||
| @ -1 +0,0 @@ | ||||
| TODO | ||||
| @ -1 +0,0 @@ | ||||
| TODO | ||||
| @ -1,32 +1,26 @@ | ||||
| package cbc | ||||
| 
 | ||||
| import ( | ||||
| 	`bytes` | ||||
| 	gAes `crypto/aes` | ||||
| 	gCipher `crypto/cipher` | ||||
| 	`io` | ||||
| 	"bytes" | ||||
| 	gCipher "crypto/cipher" | ||||
| 
 | ||||
| 	`r00t2.io/sshkeys/cipher` | ||||
| 	`r00t2.io/sshkeys/cipher/aes` | ||||
| 	`r00t2.io/sshkeys/cipher/aes/aes128` | ||||
| 	`r00t2.io/sshkeys/internal` | ||||
| 	"r00t2.io/sshkeys/internal" | ||||
| 	"r00t2.io/sshkeys/internal/ciphers/aesCommon" | ||||
| ) | ||||
| 
 | ||||
| // Setup populates a Cipher from a key. The key must include the IV suffixed to the actual key. | ||||
| func (c *Cipher) Setup(key []byte) (err error) { | ||||
| 
 | ||||
| 	if key == nil || len(key) < aes128.KdfKeySize { | ||||
| 		err = cipher.ErrBadKeyLen | ||||
| 	if c == nil { | ||||
| 		*c = Cipher{ | ||||
| 			&aesCommon.AesCipher{}, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if err = c.CipherSetup(key, aesCommon.Aes192Bits); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if c == nil { | ||||
| 		c = &Cipher{} | ||||
| 	} | ||||
| 
 | ||||
| 	c.key = key[0:aes128.KeySize] | ||||
| 	c.iv = key[aes128.KeySize:(aes128.KdfKeySize)] | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| @ -50,22 +44,6 @@ func (c *Cipher) NameBytes() (name []byte) { | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // BlockSize returns the blocksize of this Cipher. | ||||
| func (c *Cipher) BlockSize() (size int) { | ||||
| 
 | ||||
| 	size = aes.BlockSize | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // KdfKeySize returns the target key length from KDF to use with this Cipher. | ||||
| func (c *Cipher) KdfKeySize() (size int) { | ||||
| 
 | ||||
| 	size = aes128.KeySize | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Encrypt encrypts data (a string, []byte, byte, *bytes.Buffer, or *bytes.Reader) to the *bytes.Reader encrypted. | ||||
| 
 | ||||
| @ -78,33 +56,18 @@ func (c *Cipher) KdfKeySize() (size int) { | ||||
| */ | ||||
| func (c *Cipher) Encrypt(data interface{}) (encrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var padded []byte | ||||
| 	var cryptDst []byte | ||||
| 	var padded *bytes.Reader | ||||
| 	var cryptBlock gCipher.Block | ||||
| 	var crypter gCipher.BlockMode | ||||
| 
 | ||||
| 	if b, err = internal.SerializeData(data); err != nil { | ||||
| 	if cryptDst, padded, cryptBlock, err = c.GetCryptBlock(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if padded, err = c.Pad(b); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	crypter = gCipher.NewCBCEncrypter(cryptBlock, c.IV) | ||||
| 
 | ||||
| 	b = make([]byte, padded.Len()) | ||||
| 	if b, err = io.ReadAll(padded); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	cryptDst = make([]byte, len(b)) | ||||
| 
 | ||||
| 	if cryptBlock, err = gAes.NewCipher(c.key); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	crypter = gCipher.NewCBCEncrypter(cryptBlock, c.iv) | ||||
| 
 | ||||
| 	crypter.CryptBlocks(cryptDst, b) | ||||
| 	crypter.CryptBlocks(cryptDst, padded) | ||||
| 
 | ||||
| 	encrypted = bytes.NewReader(cryptDst) | ||||
| 
 | ||||
| @ -146,40 +109,6 @@ func (c *Cipher) AllocateEncrypt(data interface{}) (encrypted *bytes.Reader, err | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Pad will pad data (a string, []byte, byte, or *bytes.Buffer) to the Cipher.BlockSize (if necessary). | ||||
| 	The resulting padded buffer is returned. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Buffer, no bytes will be consumed -- the bytes are taken in entirety without consuming them (Buffer.Bytes()). | ||||
| 		  It is up to the caller to consume the buffer as desired beforehand or isolate to a specific sub-buffer beforehand to pass to Cipher.Pad. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Reader, ALL bytes WILL be consumed. | ||||
| */ | ||||
| func (c *Cipher) Pad(data interface{}) (paddedBuf *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var padNum int | ||||
| 	var pad []byte | ||||
| 	var buf *bytes.Buffer | ||||
| 
 | ||||
| 	if b, err = internal.UnpackBytes(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	buf = bytes.NewBuffer(b) | ||||
| 
 | ||||
| 	for padIdx := 1; (buf.Len() % aes.BlockSize) != 0; padIdx++ { | ||||
| 
 | ||||
| 		padNum = padIdx & cipher.PadMod | ||||
| 		pad = []byte{byte(uint32(padNum))} | ||||
| 
 | ||||
| 		if _, err = buf.Write(pad); err != nil { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Decrypt takes a raw byte slice, a *bytes.Buffer, or a *bytes.Reader and returns a plain/decrypted *bytes.Reader. | ||||
| 
 | ||||
| @ -192,25 +121,20 @@ func (c *Cipher) Pad(data interface{}) (paddedBuf *bytes.Reader, err error) { | ||||
| */ | ||||
| func (c *Cipher) Decrypt(data interface{}) (decrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var decryptDst []byte | ||||
| 	var plain []byte | ||||
| 	var padded []byte | ||||
| 	var cryptBlock gCipher.Block | ||||
| 	var decrypter gCipher.BlockMode | ||||
| 
 | ||||
| 	if b, err = internal.SerializeData(data); err != nil { | ||||
| 	if plain, padded, cryptBlock, err = c.GetDecryptBlock(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	decryptDst = make([]byte, len(b)) | ||||
| 	decrypter = gCipher.NewCBCDecrypter(cryptBlock, c.IV) | ||||
| 
 | ||||
| 	if cryptBlock, err = gAes.NewCipher(c.key); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	decrypter = gCipher.NewCBCDecrypter(cryptBlock, c.iv) | ||||
| 	decrypter.CryptBlocks(plain, padded) | ||||
| 
 | ||||
| 	decrypter.CryptBlocks(decryptDst, b) | ||||
| 
 | ||||
| 	decrypted = bytes.NewReader(decryptDst) | ||||
| 	decrypted = bytes.NewReader(plain) | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| @ -239,15 +163,3 @@ func (c *Cipher) AllocatedDecrypt(data interface{}) (decrypted *bytes.Reader, er | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	IsPlain indicates if this Cipher is a plain/null encryption (cipher.null.Null). | ||||
| 
 | ||||
| 	It will always return false. It is included for interface compatability. | ||||
| */ | ||||
| func (c *Cipher) IsPlain() (plain bool) { | ||||
| 
 | ||||
| 	plain = false | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
|  | ||||
							
								
								
									
										10
									
								
								cipher/aes/aes192/cbc/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								cipher/aes/aes192/cbc/types.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| package cbc | ||||
| 
 | ||||
| import ( | ||||
| 	"r00t2.io/sshkeys/internal/ciphers/aesCommon" | ||||
| ) | ||||
| 
 | ||||
| // Cipher is an AES128-CBC cipher.Cipher. | ||||
| type Cipher struct { | ||||
| 	*aesCommon.AesCipher | ||||
| } | ||||
| @ -1,10 +0,0 @@ | ||||
| package aes192 | ||||
| 
 | ||||
| import ( | ||||
| 	`r00t2.io/sshkeys/cipher/aes` | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	KeySize    int = 24 // in bytes; AES182 is so named for its 192-bit key, thus: 192 / 8 = 24 | ||||
| 	KdfKeySize int = KeySize + aes.IvSize | ||||
| ) | ||||
| @ -1 +0,0 @@ | ||||
| TODO | ||||
| @ -1,17 +1,25 @@ | ||||
| package ctr | ||||
| 
 | ||||
| import ( | ||||
| 	`bytes` | ||||
| 	`io` | ||||
| 	"bytes" | ||||
| 	gCipher "crypto/cipher" | ||||
| 
 | ||||
| 	`r00t2.io/sshkeys/cipher/aes` | ||||
| 	`r00t2.io/sshkeys/cipher/aes/aes128` | ||||
| 	`r00t2.io/sshkeys/internal` | ||||
| 	"r00t2.io/sshkeys/internal" | ||||
| 	"r00t2.io/sshkeys/internal/ciphers/aesCommon" | ||||
| ) | ||||
| 
 | ||||
| // Setup populates a Cipher from a key. The key must include the IV suffixed to the actual key. | ||||
| func (c *Cipher) Setup(key []byte) (err error) { | ||||
| 
 | ||||
| 	// TODO | ||||
| 	if c == nil { | ||||
| 		*c = Cipher{ | ||||
| 			&aesCommon.AesCipher{}, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if err = c.CipherSetup(key, aesCommon.Aes192Bits); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| @ -36,22 +44,6 @@ func (c *Cipher) NameBytes() (name []byte) { | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // BlockSize returns the blocksize of this Cipher. | ||||
| func (c *Cipher) BlockSize() (size int) { | ||||
| 
 | ||||
| 	size = aes.BlockSize | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // KdfKeySize returns the target key length from KDF to use with this Cipher. | ||||
| func (c *Cipher) KdfKeySize() (size int) { | ||||
| 
 | ||||
| 	size = aes128.KeySize | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Encrypt encrypts data (a string, []byte, byte, *bytes.Buffer, or *bytes.Reader) to the *bytes.Reader encrypted. | ||||
| 
 | ||||
| @ -64,27 +56,20 @@ func (c *Cipher) KdfKeySize() (size int) { | ||||
| */ | ||||
| func (c *Cipher) Encrypt(data interface{}) (encrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var padded []byte | ||||
| 	var cryptDst []byte | ||||
| 	var padded *bytes.Reader | ||||
| 	var cryptBlock gCipher.Block | ||||
| 	var crypter gCipher.Stream | ||||
| 
 | ||||
| 	if b, err = internal.SerializeData(data); err != nil { | ||||
| 	if cryptDst, padded, cryptBlock, err = c.GetCryptBlock(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if padded, err = c.Pad(b); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	crypter = gCipher.NewCTR(cryptBlock, c.IV) | ||||
| 
 | ||||
| 	b = make([]byte, padded.Len()) | ||||
| 	if b, err = io.ReadAll(padded); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	crypter.XORKeyStream(cryptDst, padded) | ||||
| 
 | ||||
| 	cryptDst = make([]byte, len(b)) | ||||
| 
 | ||||
| 	// TODO | ||||
| 	_ = cryptDst | ||||
| 	encrypted = bytes.NewReader(cryptDst) | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| @ -124,22 +109,6 @@ func (c *Cipher) AllocateEncrypt(data interface{}) (encrypted *bytes.Reader, err | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Pad will pad data (a string, []byte, byte, or *bytes.Buffer) to the Cipher.BlockSize (if necessary). | ||||
| 	The resulting padded buffer is returned. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Buffer, no bytes will be consumed -- the bytes are taken in entirety without consuming them (Buffer.Bytes()). | ||||
| 		  It is up to the caller to consume the buffer as desired beforehand or isolate to a specific sub-buffer beforehand to pass to Cipher.Pad. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Reader, ALL bytes WILL be consumed. | ||||
| */ | ||||
| func (c *Cipher) Pad(data interface{}) (paddedBuf *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	// TODO | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Decrypt takes a raw byte slice, a *bytes.Buffer, or a *bytes.Reader and returns a plain/decrypted *bytes.Reader. | ||||
| 
 | ||||
| @ -152,17 +121,20 @@ func (c *Cipher) Pad(data interface{}) (paddedBuf *bytes.Reader, err error) { | ||||
| */ | ||||
| func (c *Cipher) Decrypt(data interface{}) (decrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var decryptDst []byte | ||||
| 	var plain []byte | ||||
| 	var padded []byte | ||||
| 	var cryptBlock gCipher.Block | ||||
| 	var decrypter gCipher.Stream | ||||
| 
 | ||||
| 	if b, err = internal.SerializeData(data); err != nil { | ||||
| 	if plain, padded, cryptBlock, err = c.GetDecryptBlock(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	decryptDst = make([]byte, len(b)) | ||||
| 	decrypter = gCipher.NewCTR(cryptBlock, c.IV) | ||||
| 
 | ||||
| 	// TODO | ||||
| 	_ = decryptDst | ||||
| 	decrypter.XORKeyStream(plain, padded) | ||||
| 
 | ||||
| 	decrypted = bytes.NewReader(plain) | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| @ -191,15 +163,3 @@ func (c *Cipher) AllocatedDecrypt(data interface{}) (decrypted *bytes.Reader, er | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	IsPlain indicates if this Cipher is a plain/null encryption (cipher.null.Null). | ||||
| 
 | ||||
| 	It will always return false. It is included for interface compatability. | ||||
| */ | ||||
| func (c *Cipher) IsPlain() (plain bool) { | ||||
| 
 | ||||
| 	plain = false | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
|  | ||||
							
								
								
									
										10
									
								
								cipher/aes/aes192/ctr/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								cipher/aes/aes192/ctr/types.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| package ctr | ||||
| 
 | ||||
| import ( | ||||
| 	"r00t2.io/sshkeys/internal/ciphers/aesCommon" | ||||
| ) | ||||
| 
 | ||||
| // Cipher is an AES128-CTR cipher.Cipher. | ||||
| type Cipher struct { | ||||
| 	*aesCommon.AesCipher | ||||
| } | ||||
| @ -1 +0,0 @@ | ||||
| TODO | ||||
| @ -1,5 +0,0 @@ | ||||
| package gcm | ||||
| 
 | ||||
| const ( | ||||
| 	Name string = "aes192-gcm@openssh.com" | ||||
| ) | ||||
| @ -1,205 +0,0 @@ | ||||
| package gcm | ||||
| 
 | ||||
| import ( | ||||
| 	`bytes` | ||||
| 	`io` | ||||
| 
 | ||||
| 	`r00t2.io/sshkeys/cipher/aes` | ||||
| 	`r00t2.io/sshkeys/cipher/aes/aes128` | ||||
| 	`r00t2.io/sshkeys/internal` | ||||
| ) | ||||
| 
 | ||||
| func (c *Cipher) Setup(key []byte) (err error) { | ||||
| 
 | ||||
| 	// TODO | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Name returns the name as used in the key file bytes. | ||||
| func (c *Cipher) Name() (name string) { | ||||
| 
 | ||||
| 	name = Name | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // NameBytes returns the byte form of Cipher.Name with leading bytecount allocator. | ||||
| func (c *Cipher) NameBytes() (name []byte) { | ||||
| 
 | ||||
| 	var err error | ||||
| 
 | ||||
| 	if name, err = internal.PackBytes(Name); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // BlockSize returns the blocksize of this Cipher. | ||||
| func (c *Cipher) BlockSize() (size int) { | ||||
| 
 | ||||
| 	size = aes.BlockSize | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // KdfKeySize returns the target key length from KDF to use with this Cipher. | ||||
| func (c *Cipher) KdfKeySize() (size int) { | ||||
| 
 | ||||
| 	size = aes128.KeySize | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Encrypt encrypts data (a string, []byte, byte, *bytes.Buffer, or *bytes.Reader) to the *bytes.Reader encrypted. | ||||
| 
 | ||||
| 	NOTE: Padding IS applied automatically. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Buffer, no bytes will be consumed -- the bytes are taken in entirety without consuming them (Buffer.Bytes()). | ||||
| 		  It is up to the caller to consume the buffer as desired beforehand or isolate to a specific sub-buffer beforehand to pass to Cipher.Encrypt. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Reader, ALL bytes WILL be consumed. | ||||
| */ | ||||
| func (c *Cipher) Encrypt(data interface{}) (encrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var cryptDst []byte | ||||
| 	var padded *bytes.Reader | ||||
| 
 | ||||
| 	if b, err = internal.SerializeData(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if padded, err = c.Pad(b); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	b = make([]byte, padded.Len()) | ||||
| 	if b, err = io.ReadAll(padded); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	cryptDst = make([]byte, len(b)) | ||||
| 
 | ||||
| 	// TODO | ||||
| 	_ = cryptDst | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	AllocateEncrypt is the same as Cipher.Encrypt but includes an unencrypted byte allocator prefix. | ||||
| 
 | ||||
| 	NOTE: Padding IS applied automatically. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Buffer, no bytes will be consumed -- the bytes are taken in entirety without consuming them (Buffer.Bytes()). | ||||
| 		  It is up to the caller to consume the buffer as desired beforehand or isolate to a specific sub-buffer beforehand to pass to Cipher.AllocateEncrypt. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Reader, ALL bytes WILL be consumed. | ||||
| */ | ||||
| func (c *Cipher) AllocateEncrypt(data interface{}) (encrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b *bytes.Reader | ||||
| 	var buf *bytes.Buffer = new(bytes.Buffer) | ||||
| 	var alloc []byte = make([]byte, 4) | ||||
| 
 | ||||
| 	if b, err = c.Encrypt(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if alloc, err = internal.PackBytes(b); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = buf.Write(alloc); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if _, err = b.WriteTo(buf); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	encrypted = bytes.NewReader(buf.Bytes()) | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Pad will pad data (a string, []byte, byte, or *bytes.Buffer) to the Cipher.BlockSize (if necessary). | ||||
| 	The resulting padded buffer is returned. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Buffer, no bytes will be consumed -- the bytes are taken in entirety without consuming them (Buffer.Bytes()). | ||||
| 		  It is up to the caller to consume the buffer as desired beforehand or isolate to a specific sub-buffer beforehand to pass to Cipher.Pad. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Reader, ALL bytes WILL be consumed. | ||||
| */ | ||||
| func (c *Cipher) Pad(data interface{}) (paddedBuf *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	// TODO | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Decrypt takes a raw byte slice, a *bytes.Buffer, or a *bytes.Reader and returns a plain/decrypted *bytes.Reader. | ||||
| 
 | ||||
| 	NOTE: The decrypted data contains padding. It is up to the caller to remove/strip. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Buffer, no bytes will be consumed -- the bytes are taken in entirety without consuming them (Buffer.Bytes()). | ||||
| 		  It is up to the caller to consume the buffer as desired beforehand or isolate to a specific sub-buffer beforehand to pass to Cipher.Decrypt. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Reader, ALL bytes WILL be consumed. | ||||
| */ | ||||
| func (c *Cipher) Decrypt(data interface{}) (decrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var decryptDst []byte | ||||
| 
 | ||||
| 	if b, err = internal.SerializeData(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	decryptDst = make([]byte, len(b)) | ||||
| 
 | ||||
| 	// TODO | ||||
| 	_ = decryptDst | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	AllocatedDecrypt is the same as Cipher.Decrypt but assumes that data includes an unencrypted uint32 byte allocator prefix. | ||||
| 
 | ||||
| 	Be *extremely* certain of this, as things can get REALLY weird if you pass in data that doesn't actually have that prefix. | ||||
| 
 | ||||
| 	NOTE: The decrypted data contains padding. It is up to the caller to remove/strip. | ||||
| 
 | ||||
| 	NOTE: If data is a bytes.Buffer pointer, it will consume ONLY the leading prefix and the length of bytes the prefix indicates and no more. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Reader, it will consume ONLY the leading prefix and the length of bytes the prefix indicates and no more. | ||||
| */ | ||||
| func (c *Cipher) AllocatedDecrypt(data interface{}) (decrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 
 | ||||
| 	if b, err = internal.UnpackBytes(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if decrypted, err = c.Decrypt(b); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	IsPlain indicates if this Cipher is a plain/null encryption (cipher.null.Null). | ||||
| 
 | ||||
| 	It will always return false. It is included for interface compatability. | ||||
| */ | ||||
| func (c *Cipher) IsPlain() (plain bool) { | ||||
| 
 | ||||
| 	plain = false | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| @ -1 +0,0 @@ | ||||
| TODO | ||||
| @ -1,32 +1,26 @@ | ||||
| package cbc | ||||
| 
 | ||||
| import ( | ||||
| 	`bytes` | ||||
| 	gAes `crypto/aes` | ||||
| 	gCipher `crypto/cipher` | ||||
| 	`io` | ||||
| 	"bytes" | ||||
| 	gCipher "crypto/cipher" | ||||
| 
 | ||||
| 	`r00t2.io/sshkeys/cipher` | ||||
| 	`r00t2.io/sshkeys/cipher/aes` | ||||
| 	`r00t2.io/sshkeys/cipher/aes/aes128` | ||||
| 	`r00t2.io/sshkeys/internal` | ||||
| 	"r00t2.io/sshkeys/internal" | ||||
| 	"r00t2.io/sshkeys/internal/ciphers/aesCommon" | ||||
| ) | ||||
| 
 | ||||
| // Setup populates a Cipher from a key. The key must include the IV suffixed to the actual key. | ||||
| func (c *Cipher) Setup(key []byte) (err error) { | ||||
| 
 | ||||
| 	if key == nil || len(key) < aes128.KdfKeySize { | ||||
| 		err = cipher.ErrBadKeyLen | ||||
| 	if c == nil { | ||||
| 		*c = Cipher{ | ||||
| 			&aesCommon.AesCipher{}, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if err = c.CipherSetup(key, aesCommon.Aes256Bits); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if c == nil { | ||||
| 		c = &Cipher{} | ||||
| 	} | ||||
| 
 | ||||
| 	c.key = key[0:aes128.KeySize] | ||||
| 	c.iv = key[aes128.KeySize:(aes128.KdfKeySize)] | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| @ -50,22 +44,6 @@ func (c *Cipher) NameBytes() (name []byte) { | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // BlockSize returns the blocksize of this Cipher. | ||||
| func (c *Cipher) BlockSize() (size int) { | ||||
| 
 | ||||
| 	size = aes.BlockSize | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // KdfKeySize returns the target key length from KDF to use with this Cipher. | ||||
| func (c *Cipher) KdfKeySize() (size int) { | ||||
| 
 | ||||
| 	size = aes128.KeySize | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Encrypt encrypts data (a string, []byte, byte, *bytes.Buffer, or *bytes.Reader) to the *bytes.Reader encrypted. | ||||
| 
 | ||||
| @ -78,33 +56,18 @@ func (c *Cipher) KdfKeySize() (size int) { | ||||
| */ | ||||
| func (c *Cipher) Encrypt(data interface{}) (encrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var padded []byte | ||||
| 	var cryptDst []byte | ||||
| 	var padded *bytes.Reader | ||||
| 	var cryptBlock gCipher.Block | ||||
| 	var crypter gCipher.BlockMode | ||||
| 
 | ||||
| 	if b, err = internal.SerializeData(data); err != nil { | ||||
| 	if cryptDst, padded, cryptBlock, err = c.GetCryptBlock(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if padded, err = c.Pad(b); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	crypter = gCipher.NewCBCEncrypter(cryptBlock, c.IV) | ||||
| 
 | ||||
| 	b = make([]byte, padded.Len()) | ||||
| 	if b, err = io.ReadAll(padded); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	cryptDst = make([]byte, len(b)) | ||||
| 
 | ||||
| 	if cryptBlock, err = gAes.NewCipher(c.key); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	crypter = gCipher.NewCBCEncrypter(cryptBlock, c.iv) | ||||
| 
 | ||||
| 	crypter.CryptBlocks(cryptDst, b) | ||||
| 	crypter.CryptBlocks(cryptDst, padded) | ||||
| 
 | ||||
| 	encrypted = bytes.NewReader(cryptDst) | ||||
| 
 | ||||
| @ -146,40 +109,6 @@ func (c *Cipher) AllocateEncrypt(data interface{}) (encrypted *bytes.Reader, err | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Pad will pad data (a string, []byte, byte, or *bytes.Buffer) to the Cipher.BlockSize (if necessary). | ||||
| 	The resulting padded buffer is returned. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Buffer, no bytes will be consumed -- the bytes are taken in entirety without consuming them (Buffer.Bytes()). | ||||
| 		  It is up to the caller to consume the buffer as desired beforehand or isolate to a specific sub-buffer beforehand to pass to Cipher.Pad. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Reader, ALL bytes WILL be consumed. | ||||
| */ | ||||
| func (c *Cipher) Pad(data interface{}) (paddedBuf *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var padNum int | ||||
| 	var pad []byte | ||||
| 	var buf *bytes.Buffer | ||||
| 
 | ||||
| 	if b, err = internal.UnpackBytes(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	buf = bytes.NewBuffer(b) | ||||
| 
 | ||||
| 	for padIdx := 1; (buf.Len() % aes.BlockSize) != 0; padIdx++ { | ||||
| 
 | ||||
| 		padNum = padIdx & cipher.PadMod | ||||
| 		pad = []byte{byte(uint32(padNum))} | ||||
| 
 | ||||
| 		if _, err = buf.Write(pad); err != nil { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Decrypt takes a raw byte slice, a *bytes.Buffer, or a *bytes.Reader and returns a plain/decrypted *bytes.Reader. | ||||
| 
 | ||||
| @ -192,25 +121,20 @@ func (c *Cipher) Pad(data interface{}) (paddedBuf *bytes.Reader, err error) { | ||||
| */ | ||||
| func (c *Cipher) Decrypt(data interface{}) (decrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var decryptDst []byte | ||||
| 	var plain []byte | ||||
| 	var padded []byte | ||||
| 	var cryptBlock gCipher.Block | ||||
| 	var decrypter gCipher.BlockMode | ||||
| 
 | ||||
| 	if b, err = internal.SerializeData(data); err != nil { | ||||
| 	if plain, padded, cryptBlock, err = c.GetDecryptBlock(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	decryptDst = make([]byte, len(b)) | ||||
| 	decrypter = gCipher.NewCBCDecrypter(cryptBlock, c.IV) | ||||
| 
 | ||||
| 	if cryptBlock, err = gAes.NewCipher(c.key); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	decrypter = gCipher.NewCBCDecrypter(cryptBlock, c.iv) | ||||
| 	decrypter.CryptBlocks(plain, padded) | ||||
| 
 | ||||
| 	decrypter.CryptBlocks(decryptDst, b) | ||||
| 
 | ||||
| 	decrypted = bytes.NewReader(decryptDst) | ||||
| 	decrypted = bytes.NewReader(plain) | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| @ -239,15 +163,3 @@ func (c *Cipher) AllocatedDecrypt(data interface{}) (decrypted *bytes.Reader, er | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	IsPlain indicates if this Cipher is a plain/null encryption (cipher.null.Null). | ||||
| 
 | ||||
| 	It will always return false. It is included for interface compatability. | ||||
| */ | ||||
| func (c *Cipher) IsPlain() (plain bool) { | ||||
| 
 | ||||
| 	plain = false | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
|  | ||||
							
								
								
									
										10
									
								
								cipher/aes/aes256/cbc/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								cipher/aes/aes256/cbc/types.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| package cbc | ||||
| 
 | ||||
| import ( | ||||
| 	"r00t2.io/sshkeys/internal/ciphers/aesCommon" | ||||
| ) | ||||
| 
 | ||||
| // Cipher is an AES128-CBC cipher.Cipher. | ||||
| type Cipher struct { | ||||
| 	*aesCommon.AesCipher | ||||
| } | ||||
| @ -1,10 +0,0 @@ | ||||
| package aes256 | ||||
| 
 | ||||
| import ( | ||||
| 	`r00t2.io/sshkeys/cipher/aes` | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	KeySize    int = 32 // in bytes; AES256 is so named for its 256-bit key, thus: 256 / 8 = 32 | ||||
| 	KdfKeySize int = KeySize + aes.IvSize | ||||
| ) | ||||
| @ -1 +0,0 @@ | ||||
| TODO | ||||
| @ -1,17 +1,25 @@ | ||||
| package ctr | ||||
| 
 | ||||
| import ( | ||||
| 	`bytes` | ||||
| 	`io` | ||||
| 	"bytes" | ||||
| 	gCipher "crypto/cipher" | ||||
| 
 | ||||
| 	`r00t2.io/sshkeys/cipher/aes` | ||||
| 	`r00t2.io/sshkeys/cipher/aes/aes128` | ||||
| 	`r00t2.io/sshkeys/internal` | ||||
| 	"r00t2.io/sshkeys/internal" | ||||
| 	"r00t2.io/sshkeys/internal/ciphers/aesCommon" | ||||
| ) | ||||
| 
 | ||||
| // Setup populates a Cipher from a key. The key must include the IV suffixed to the actual key. | ||||
| func (c *Cipher) Setup(key []byte) (err error) { | ||||
| 
 | ||||
| 	// TODO | ||||
| 	if c == nil { | ||||
| 		*c = Cipher{ | ||||
| 			&aesCommon.AesCipher{}, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if err = c.CipherSetup(key, aesCommon.Aes256Bits); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| @ -36,22 +44,6 @@ func (c *Cipher) NameBytes() (name []byte) { | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // BlockSize returns the blocksize of this Cipher. | ||||
| func (c *Cipher) BlockSize() (size int) { | ||||
| 
 | ||||
| 	size = aes.BlockSize | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // KdfKeySize returns the target key length from KDF to use with this Cipher. | ||||
| func (c *Cipher) KdfKeySize() (size int) { | ||||
| 
 | ||||
| 	size = aes128.KeySize | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Encrypt encrypts data (a string, []byte, byte, *bytes.Buffer, or *bytes.Reader) to the *bytes.Reader encrypted. | ||||
| 
 | ||||
| @ -64,27 +56,20 @@ func (c *Cipher) KdfKeySize() (size int) { | ||||
| */ | ||||
| func (c *Cipher) Encrypt(data interface{}) (encrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var padded []byte | ||||
| 	var cryptDst []byte | ||||
| 	var padded *bytes.Reader | ||||
| 	var cryptBlock gCipher.Block | ||||
| 	var crypter gCipher.Stream | ||||
| 
 | ||||
| 	if b, err = internal.SerializeData(data); err != nil { | ||||
| 	if cryptDst, padded, cryptBlock, err = c.GetCryptBlock(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if padded, err = c.Pad(b); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	crypter = gCipher.NewCTR(cryptBlock, c.IV) | ||||
| 
 | ||||
| 	b = make([]byte, padded.Len()) | ||||
| 	if b, err = io.ReadAll(padded); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	crypter.XORKeyStream(cryptDst, padded) | ||||
| 
 | ||||
| 	cryptDst = make([]byte, len(b)) | ||||
| 
 | ||||
| 	// TODO | ||||
| 	_ = cryptDst | ||||
| 	encrypted = bytes.NewReader(cryptDst) | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| @ -124,22 +109,6 @@ func (c *Cipher) AllocateEncrypt(data interface{}) (encrypted *bytes.Reader, err | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Pad will pad data (a string, []byte, byte, or *bytes.Buffer) to the Cipher.BlockSize (if necessary). | ||||
| 	The resulting padded buffer is returned. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Buffer, no bytes will be consumed -- the bytes are taken in entirety without consuming them (Buffer.Bytes()). | ||||
| 		  It is up to the caller to consume the buffer as desired beforehand or isolate to a specific sub-buffer beforehand to pass to Cipher.Pad. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Reader, ALL bytes WILL be consumed. | ||||
| */ | ||||
| func (c *Cipher) Pad(data interface{}) (paddedBuf *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	// TODO | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Decrypt takes a raw byte slice, a *bytes.Buffer, or a *bytes.Reader and returns a plain/decrypted *bytes.Reader. | ||||
| 
 | ||||
| @ -152,17 +121,20 @@ func (c *Cipher) Pad(data interface{}) (paddedBuf *bytes.Reader, err error) { | ||||
| */ | ||||
| func (c *Cipher) Decrypt(data interface{}) (decrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var decryptDst []byte | ||||
| 	var plain []byte | ||||
| 	var padded []byte | ||||
| 	var cryptBlock gCipher.Block | ||||
| 	var decrypter gCipher.Stream | ||||
| 
 | ||||
| 	if b, err = internal.SerializeData(data); err != nil { | ||||
| 	if plain, padded, cryptBlock, err = c.GetDecryptBlock(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	decryptDst = make([]byte, len(b)) | ||||
| 	decrypter = gCipher.NewCTR(cryptBlock, c.IV) | ||||
| 
 | ||||
| 	// TODO | ||||
| 	_ = decryptDst | ||||
| 	decrypter.XORKeyStream(plain, padded) | ||||
| 
 | ||||
| 	decrypted = bytes.NewReader(plain) | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| @ -191,15 +163,3 @@ func (c *Cipher) AllocatedDecrypt(data interface{}) (decrypted *bytes.Reader, er | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	IsPlain indicates if this Cipher is a plain/null encryption (cipher.null.Null). | ||||
| 
 | ||||
| 	It will always return false. It is included for interface compatability. | ||||
| */ | ||||
| func (c *Cipher) IsPlain() (plain bool) { | ||||
| 
 | ||||
| 	plain = false | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
|  | ||||
							
								
								
									
										10
									
								
								cipher/aes/aes256/ctr/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								cipher/aes/aes256/ctr/types.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| package ctr | ||||
| 
 | ||||
| import ( | ||||
| 	"r00t2.io/sshkeys/internal/ciphers/aesCommon" | ||||
| ) | ||||
| 
 | ||||
| // Cipher is an AES128-CTR cipher.Cipher. | ||||
| type Cipher struct { | ||||
| 	*aesCommon.AesCipher | ||||
| } | ||||
| @ -1 +0,0 @@ | ||||
| TODO | ||||
| @ -1,17 +1,25 @@ | ||||
| package gcm | ||||
| 
 | ||||
| import ( | ||||
| 	`bytes` | ||||
| 	`io` | ||||
| 	"bytes" | ||||
| 	gCipher "crypto/cipher" | ||||
| 
 | ||||
| 	`r00t2.io/sshkeys/cipher/aes` | ||||
| 	`r00t2.io/sshkeys/cipher/aes/aes128` | ||||
| 	`r00t2.io/sshkeys/internal` | ||||
| 	"r00t2.io/sshkeys/internal" | ||||
| 	"r00t2.io/sshkeys/internal/ciphers/aesCommon" | ||||
| ) | ||||
| 
 | ||||
| // Setup populates a Cipher from a key. The key must include the IV suffixed to the actual key. | ||||
| func (c *Cipher) Setup(key []byte) (err error) { | ||||
| 
 | ||||
| 	// TODO | ||||
| 	if c == nil { | ||||
| 		*c = Cipher{ | ||||
| 			&aesCommon.AesCipher{}, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if err = c.CipherSetup(key, aesCommon.Aes256Bits); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| @ -36,22 +44,6 @@ func (c *Cipher) NameBytes() (name []byte) { | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // BlockSize returns the blocksize of this Cipher. | ||||
| func (c *Cipher) BlockSize() (size int) { | ||||
| 
 | ||||
| 	size = aes.BlockSize | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // KdfKeySize returns the target key length from KDF to use with this Cipher. | ||||
| func (c *Cipher) KdfKeySize() (size int) { | ||||
| 
 | ||||
| 	size = aes128.KeySize | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Encrypt encrypts data (a string, []byte, byte, *bytes.Buffer, or *bytes.Reader) to the *bytes.Reader encrypted. | ||||
| 
 | ||||
| @ -64,27 +56,22 @@ func (c *Cipher) KdfKeySize() (size int) { | ||||
| */ | ||||
| func (c *Cipher) Encrypt(data interface{}) (encrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var padded []byte | ||||
| 	var cryptDst []byte | ||||
| 	var padded *bytes.Reader | ||||
| 	var cryptBlock gCipher.Block | ||||
| 	var crypter gCipher.AEAD | ||||
| 
 | ||||
| 	if b, err = internal.SerializeData(data); err != nil { | ||||
| 	if cryptDst, padded, cryptBlock, err = c.GetCryptBlock(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if padded, err = c.Pad(b); err != nil { | ||||
| 	if crypter, err = gCipher.NewGCM(cryptBlock); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	b = make([]byte, padded.Len()) | ||||
| 	if b, err = io.ReadAll(padded); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	cryptDst = crypter.Seal(cryptDst, c.IV, padded, nil) | ||||
| 
 | ||||
| 	cryptDst = make([]byte, len(b)) | ||||
| 
 | ||||
| 	// TODO | ||||
| 	_ = cryptDst | ||||
| 	encrypted = bytes.NewReader(cryptDst) | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| @ -124,22 +111,6 @@ func (c *Cipher) AllocateEncrypt(data interface{}) (encrypted *bytes.Reader, err | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Pad will pad data (a string, []byte, byte, or *bytes.Buffer) to the Cipher.BlockSize (if necessary). | ||||
| 	The resulting padded buffer is returned. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Buffer, no bytes will be consumed -- the bytes are taken in entirety without consuming them (Buffer.Bytes()). | ||||
| 		  It is up to the caller to consume the buffer as desired beforehand or isolate to a specific sub-buffer beforehand to pass to Cipher.Pad. | ||||
| 
 | ||||
| 	NOTE: If data is a *bytes.Reader, ALL bytes WILL be consumed. | ||||
| */ | ||||
| func (c *Cipher) Pad(data interface{}) (paddedBuf *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	// TODO | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	Decrypt takes a raw byte slice, a *bytes.Buffer, or a *bytes.Reader and returns a plain/decrypted *bytes.Reader. | ||||
| 
 | ||||
| @ -152,17 +123,24 @@ func (c *Cipher) Pad(data interface{}) (paddedBuf *bytes.Reader, err error) { | ||||
| */ | ||||
| func (c *Cipher) Decrypt(data interface{}) (decrypted *bytes.Reader, err error) { | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	var decryptDst []byte | ||||
| 	var plain []byte | ||||
| 	var padded []byte | ||||
| 	var cryptBlock gCipher.Block | ||||
| 	var decrypter gCipher.AEAD | ||||
| 
 | ||||
| 	if b, err = internal.SerializeData(data); err != nil { | ||||
| 	if plain, padded, cryptBlock, err = c.GetDecryptBlock(data); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	decryptDst = make([]byte, len(b)) | ||||
| 	if decrypter, err = gCipher.NewGCM(cryptBlock); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO | ||||
| 	_ = decryptDst | ||||
| 	if plain, err = decrypter.Open(plain, c.IV, padded, nil); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	decrypted = bytes.NewReader(plain) | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| @ -191,15 +169,3 @@ func (c *Cipher) AllocatedDecrypt(data interface{}) (decrypted *bytes.Reader, er | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 	IsPlain indicates if this Cipher is a plain/null encryption (cipher.null.Null). | ||||
| 
 | ||||
| 	It will always return false. It is included for interface compatability. | ||||
| */ | ||||
| func (c *Cipher) IsPlain() (plain bool) { | ||||
| 
 | ||||
| 	plain = false | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
|  | ||||
							
								
								
									
										10
									
								
								cipher/aes/aes256/gcm/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								cipher/aes/aes256/gcm/types.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| package gcm | ||||
| 
 | ||||
| import ( | ||||
| 	"r00t2.io/sshkeys/internal/ciphers/aesCommon" | ||||
| ) | ||||
| 
 | ||||
| // Cipher is an AES128-GCM cipher.Cipher. | ||||
| type Cipher struct { | ||||
| 	*aesCommon.AesCipher | ||||
| } | ||||
| @ -1,10 +0,0 @@ | ||||
| package aes | ||||
| 
 | ||||
| import ( | ||||
| 	`crypto/aes` | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	BlockSize int = aes.BlockSize | ||||
| 	IvSize    int = aes.BlockSize | ||||
| ) | ||||
| @ -2,6 +2,6 @@ package aesCommon | ||||
| 
 | ||||
| const ( | ||||
| 	Aes128Bits aesBitSize = 128 | ||||
| 	Aes196Bits aesBitSize = 196 | ||||
| 	Aes192Bits aesBitSize = 192 | ||||
| 	Aes256Bits aesBitSize = 256 | ||||
| ) | ||||
|  | ||||
| @ -16,7 +16,7 @@ type AesCipher struct { | ||||
| 	/* | ||||
| 		KeyLen is the length of key used (in bytes) (int(AesCipher.Bits) / 8). | ||||
| 
 | ||||
| 		Must be one of 16 (128-bit), 24 (195-bit), or 32 (256-bit). | ||||
| 		Must be one of 16 (128-bit), 24 (192-bit), or 32 (256-bit). | ||||
| 	*/ | ||||
| 	KeyLen int `validate:"oneof=16 24 32"` | ||||
| 	// Bits is the full bit length of AesCipher.KeyLen (in bits) (AesCipher.KeyLen * 8) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user