Skip to content

Commit

Permalink
restructure files
Browse files Browse the repository at this point in the history
  • Loading branch information
hbakhtiyor committed Jan 1, 2019
1 parent 90d2bce commit 34a1fd3
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 107 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# OpenSSL GCM
AES GCM Encryption/Decryption I/O streams

## See
* https://github.com/minio/sio/

## Credits
* https://github.com/aws/aws-sdk-go/blob/master/service/s3/s3crypto/aes_gcm.go
* https://github.com/catalyzeio/gcm/blob/master/gcm/gcm.go
* https://github.com/spacemonkeygo/openssl/blob/master/ciphers_test.go
* https://github.com/marcopaganini/iocrypt/blob/master/iocrypt.go

51 changes: 51 additions & 0 deletions examples/decrypt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package main

import (
"encoding/hex"
"fmt"
"io"
"os"

aesgcm "github.com/hbakhtiyor/openssl_gcm"
)

// DecryptFile decrypts the file at the specified path using GCM.
func DecryptFile(inFilePath, outFilePath string, key, iv, aad []byte) error {
stat, err := os.Stat(inFilePath)
if os.IsNotExist(err) {
return fmt.Errorf("A file does not exist at %s", inFilePath)
} else if err != nil {
return err
}

inFile, err := os.Open(inFilePath)
if err != nil {
return err
}
defer inFile.Close()

outFile, err := os.Create(outFilePath)
if err != nil {
return err
}
defer outFile.Close()

r, err := aesgcm.NewGcmDecryptReader(inFile, key, iv, aad, stat.Size())
if err != nil {
return err
}

_, err = io.Copy(outFile, r)
return err
}

func main() {
inFilePath := "testdata.enc"
outFilePath := "testdata"
key, _ := hex.DecodeString("81be5e09c111576103a8507658d47891")
iv, _ := hex.DecodeString("81be5e09c111576103a85076")

if err := DecryptFile(inFilePath, outFilePath, key, iv, nil); err != nil {
panic(err)
}
}
38 changes: 3 additions & 35 deletions cipher_example.go → examples/encrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"io"
"os"

aesgcm "github.com/hbakhtiyor/openssl_gcm"
)

// EncryptFile encrypts the file at the specified path using GCM.
Expand All @@ -27,37 +29,7 @@ func EncryptFile(inFilePath, outFilePath string, key, iv, aad []byte) error {
}
defer outFile.Close()

r, err := NewGcmEncryptReader(inFile, key, iv, aad)
if err != nil {
return err
}

_, err = io.Copy(outFile, r)
return err
}

// DecryptFile decrypts the file at the specified path using GCM.
func DecryptFile(inFilePath, outFilePath string, key, iv, aad []byte) error {
stat, err := os.Stat(inFilePath)
if os.IsNotExist(err) {
return fmt.Errorf("A file does not exist at %s", inFilePath)
} else if err != nil {
return err
}

inFile, err := os.Open(inFilePath)
if err != nil {
return err
}
defer inFile.Close()

outFile, err := os.Create(outFilePath)
if err != nil {
return err
}
defer outFile.Close()

r, err := NewGcmDecryptReader(inFile, key, iv, aad, stat.Size())
r, err := aesgcm.NewGcmEncryptReader(inFile, key, iv, aad)
if err != nil {
return err
}
Expand All @@ -69,14 +41,10 @@ func DecryptFile(inFilePath, outFilePath string, key, iv, aad []byte) error {
func main() {
inFilePath := "testdata"
outFilePath := "testdata.enc"
outNewFilePath := "newtestdata"
key, _ := hex.DecodeString("81be5e09c111576103a8507658d47891")
iv, _ := hex.DecodeString("81be5e09c111576103a85076")

if err := EncryptFile(inFilePath, outFilePath, key, iv, nil); err != nil {
panic(err)
}
if err := DecryptFile(outFilePath, outNewFilePath, key, iv, nil); err != nil {
panic(err)
}
}
73 changes: 1 addition & 72 deletions cipher.go → gcm_decrypt_reader.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// package cipher
package main
package openssl_gcm

import (
"bytes"
Expand All @@ -9,80 +8,10 @@ import (
"github.com/spacemonkeygo/openssl"
)

// Credits
// https://github.com/aws/aws-sdk-go/blob/master/service/s3/s3crypto/aes_gcm.go
// https://github.com/catalyzeio/gcm/blob/master/gcm/gcm.go
// https://github.com/spacemonkeygo/openssl/blob/master/ciphers_test.go
// https://github.com/marcopaganini/iocrypt/blob/master/iocrypt.go
// https://github.com/minio/sio/tree/master/cmd/ncrypt

const (
GcmTagMaxlen = openssl.GCM_TAG_MAXLEN
)

type gcmEncryptReader struct {
src io.Reader
ctx openssl.AuthenticatedEncryptionCipherCtx
eof bool
buf *bytes.Buffer // for finalize small bytes
}

func NewGcmEncryptReader(r io.Reader, key, iv, aad []byte) (*gcmEncryptReader, error) {
ctx, err := openssl.NewGCMEncryptionCipherCtx(len(key)*8, nil, key, iv)
if err != nil {
return nil, fmt.Errorf("Failed making GCM encryption ctx: %v", err)
}

if len(aad) > 0 {
err = ctx.ExtraData(aad)
if err != nil {
return nil, fmt.Errorf("Failed to add authenticated data: %v", err)
}
}

return &gcmEncryptReader{
src: r,
ctx: ctx,
buf: &bytes.Buffer{},
}, nil
}

func (r *gcmEncryptReader) Read(p []byte) (int, error) {
if r.eof {
return r.buf.Read(p)
}

n, err := r.src.Read(p)

if err == io.EOF {
data, err := r.ctx.EncryptFinal()
if err != nil {
return len(data), fmt.Errorf("Failed to finalize encryption: %v", err)
}
r.buf.Write(data)

tag, err := r.ctx.GetTag()
if err != nil {
return len(data) + len(tag), fmt.Errorf("Failed to get GCM tag: %v", err)
}
r.buf.Write(tag)

r.eof = true

return r.buf.Read(p)
} else if err != nil {
return n, err
}

data, err := r.ctx.EncryptUpdate(p[:n])
if err != nil {
return len(data), fmt.Errorf("Failed to perform an encryption: %v", err)
}
copy(p, data)

return n, nil
}

type gcmDecryptReader struct {
src io.Reader
ctx openssl.AuthenticatedDecryptionCipherCtx
Expand Down
72 changes: 72 additions & 0 deletions gcm_encrypt_reader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package openssl_gcm

import (
"bytes"
"fmt"
"io"

"github.com/spacemonkeygo/openssl"
)

type gcmEncryptReader struct {
src io.Reader
ctx openssl.AuthenticatedEncryptionCipherCtx
eof bool
buf *bytes.Buffer // for finalize small bytes
}

func NewGcmEncryptReader(r io.Reader, key, iv, aad []byte) (*gcmEncryptReader, error) {
ctx, err := openssl.NewGCMEncryptionCipherCtx(len(key)*8, nil, key, iv)
if err != nil {
return nil, fmt.Errorf("Failed making GCM encryption ctx: %v", err)
}

if len(aad) > 0 {
err = ctx.ExtraData(aad)
if err != nil {
return nil, fmt.Errorf("Failed to add authenticated data: %v", err)
}
}

return &gcmEncryptReader{
src: r,
ctx: ctx,
buf: &bytes.Buffer{},
}, nil
}

func (r *gcmEncryptReader) Read(p []byte) (int, error) {
if r.eof {
return r.buf.Read(p)
}

n, err := r.src.Read(p)

if err == io.EOF {
data, err := r.ctx.EncryptFinal()
if err != nil {
return len(data), fmt.Errorf("Failed to finalize encryption: %v", err)
}
r.buf.Write(data)

tag, err := r.ctx.GetTag()
if err != nil {
return len(data) + len(tag), fmt.Errorf("Failed to get GCM tag: %v", err)
}
r.buf.Write(tag)

r.eof = true

return r.buf.Read(p)
} else if err != nil {
return n, err
}

data, err := r.ctx.EncryptUpdate(p[:n])
if err != nil {
return len(data), fmt.Errorf("Failed to perform an encryption: %v", err)
}
copy(p, data)

return n, nil
}

0 comments on commit 34a1fd3

Please sign in to comment.