From 646d2d54cea75ec550f015a9eb61ba1642730908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Connes?= Date: Tue, 26 May 2020 23:19:08 +0200 Subject: [PATCH] Replace ctrutil with cipherio for AES-CBC --- cia.go | 4 +- ctrutil/cipher.go | 101 ---------------------------------------------- go.mod | 1 + 3 files changed, 4 insertions(+), 102 deletions(-) delete mode 100644 ctrutil/cipher.go diff --git a/cia.go b/cia.go index 1a5ba93..b8f6138 100644 --- a/cia.go +++ b/cia.go @@ -10,6 +10,8 @@ import ( "io" "io/ioutil" + "github.com/connesc/cipherio" + "github.com/connesc/ctrsigcheck/ctrutil" ) @@ -217,7 +219,7 @@ func CheckCIA(input io.Reader) (*CIA, error) { } contentIV := make([]byte, contentCipher.BlockSize()) binary.BigEndian.PutUint16(contentIV, uint16(content.Index)) - data = ctrutil.NewCipherReader(data, cipher.NewCBCDecrypter(contentCipher, contentIV)) + data = cipherio.NewBlockReader(data, cipher.NewCBCDecrypter(contentCipher, contentIV)) } hash := sha256.New() diff --git a/ctrutil/cipher.go b/ctrutil/cipher.go deleted file mode 100644 index 8801aaf..0000000 --- a/ctrutil/cipher.go +++ /dev/null @@ -1,101 +0,0 @@ -package ctrutil - -import ( - "crypto/cipher" - "io" -) - -type cipherReader struct { - src io.Reader - blockMode cipher.BlockMode - blockSize int - buf []byte // used to store remaining bytes (before or after crypting) - crypted int // if > 0, then buf contains remaining crypted bytes - eof bool -} - -// NewCipherReader wraps the given Reader to add on-the-fly encryption or decryption using the -// given BlockMode. -// -// The input must be aligned to the cipher block size: ErrUnexpectedEOF is returned if EOF is -// reached in the middle of a block. -// -// This Reader limits buffering and copies to the minimum: lookahead can only happen if the last -// requested block is incomplete. In that case, it is guaranteed that the wrapped Reader is never -// read beyond the end of the incomplete block. In particular, it is safe to stop reading from this -// Reader at a block boundary and then start using the wrapped Reader for something else. -func NewCipherReader(src io.Reader, blockMode cipher.BlockMode) io.Reader { - blockSize := blockMode.BlockSize() - - return &cipherReader{ - src: src, - blockMode: blockMode, - blockSize: blockSize, - buf: make([]byte, 0, blockSize), - crypted: 0, - eof: false, - } -} - -func (r *cipherReader) Read(p []byte) (int, error) { - count := 0 - - if r.crypted > 0 { - copied := copy(p, r.buf[r.blockSize-r.crypted:]) - p = p[copied:] - count += copied - r.crypted -= copied - if r.crypted > 0 { - return count, nil - } - r.buf = r.buf[:0] - } - - if r.eof { - return count, io.EOF - } - if len(p) == 0 { - return count, nil - } - - if len(p) < r.blockSize { - n, err := r.src.Read(r.buf[len(r.buf):r.blockSize]) - r.buf = r.buf[:len(r.buf)+n] - if len(r.buf) == r.blockSize { - r.blockMode.CryptBlocks(r.buf, r.buf) - copied := copy(p, r.buf) - count += copied - r.crypted = r.blockSize - copied - } - if err == io.EOF { - if r.crypted > 0 { - err = nil - r.eof = true - } else if len(r.buf) > 0 { - err = io.ErrUnexpectedEOF - } - } - return count, err - } - - n, err := r.src.Read(p[len(r.buf):]) - available := len(r.buf) + n - buffered := available % r.blockSize - crypted := available - buffered - - if crypted > 0 { - copy(p, r.buf) - r.buf = r.buf[:0] - r.blockMode.CryptBlocks(p[:crypted], p[:crypted]) - count += crypted - } - - newlyBuffered := buffered - len(r.buf) - r.buf = r.buf[:buffered] - copy(r.buf[buffered-newlyBuffered:], p[available-newlyBuffered:]) - - if err == io.EOF && buffered > 0 { - err = io.ErrUnexpectedEOF - } - return count, err -} diff --git a/go.mod b/go.mod index 6677af5..0b89fc8 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/connesc/ctrsigcheck go 1.14 require ( + github.com/connesc/cipherio v0.1.0 github.com/spf13/cobra v1.0.0 github.com/spf13/pflag v1.0.3 )