mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-25 18:21:26 +02:00 
			
		
		
		
	* Switch to keybase go-crypto (for some elliptic curve key) + test
* Use assert.NoError 
and add a little more context to failing test description
* Use assert.(No)Error everywhere 🌈
and assert.Error in place of .Nil/.NotNil
		
	
			
		
			
				
	
	
		
			144 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
| // Copyright 2010 The Go Authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| // OpenPGP CFB Mode. http://tools.ietf.org/html/rfc4880#section-13.9
 | |
| 
 | |
| package packet
 | |
| 
 | |
| import (
 | |
| 	"crypto/cipher"
 | |
| )
 | |
| 
 | |
| type ocfbEncrypter struct {
 | |
| 	b       cipher.Block
 | |
| 	fre     []byte
 | |
| 	outUsed int
 | |
| }
 | |
| 
 | |
| // An OCFBResyncOption determines if the "resynchronization step" of OCFB is
 | |
| // performed.
 | |
| type OCFBResyncOption bool
 | |
| 
 | |
| const (
 | |
| 	OCFBResync   OCFBResyncOption = true
 | |
| 	OCFBNoResync OCFBResyncOption = false
 | |
| )
 | |
| 
 | |
| // NewOCFBEncrypter returns a cipher.Stream which encrypts data with OpenPGP's
 | |
| // cipher feedback mode using the given cipher.Block, and an initial amount of
 | |
| // ciphertext.  randData must be random bytes and be the same length as the
 | |
| // cipher.Block's block size. Resync determines if the "resynchronization step"
 | |
| // from RFC 4880, 13.9 step 7 is performed. Different parts of OpenPGP vary on
 | |
| // this point.
 | |
| func NewOCFBEncrypter(block cipher.Block, randData []byte, resync OCFBResyncOption) (cipher.Stream, []byte) {
 | |
| 	blockSize := block.BlockSize()
 | |
| 	if len(randData) != blockSize {
 | |
| 		return nil, nil
 | |
| 	}
 | |
| 
 | |
| 	x := &ocfbEncrypter{
 | |
| 		b:       block,
 | |
| 		fre:     make([]byte, blockSize),
 | |
| 		outUsed: 0,
 | |
| 	}
 | |
| 	prefix := make([]byte, blockSize+2)
 | |
| 
 | |
| 	block.Encrypt(x.fre, x.fre)
 | |
| 	for i := 0; i < blockSize; i++ {
 | |
| 		prefix[i] = randData[i] ^ x.fre[i]
 | |
| 	}
 | |
| 
 | |
| 	block.Encrypt(x.fre, prefix[:blockSize])
 | |
| 	prefix[blockSize] = x.fre[0] ^ randData[blockSize-2]
 | |
| 	prefix[blockSize+1] = x.fre[1] ^ randData[blockSize-1]
 | |
| 
 | |
| 	if resync {
 | |
| 		block.Encrypt(x.fre, prefix[2:])
 | |
| 	} else {
 | |
| 		x.fre[0] = prefix[blockSize]
 | |
| 		x.fre[1] = prefix[blockSize+1]
 | |
| 		x.outUsed = 2
 | |
| 	}
 | |
| 	return x, prefix
 | |
| }
 | |
| 
 | |
| func (x *ocfbEncrypter) XORKeyStream(dst, src []byte) {
 | |
| 	for i := 0; i < len(src); i++ {
 | |
| 		if x.outUsed == len(x.fre) {
 | |
| 			x.b.Encrypt(x.fre, x.fre)
 | |
| 			x.outUsed = 0
 | |
| 		}
 | |
| 
 | |
| 		x.fre[x.outUsed] ^= src[i]
 | |
| 		dst[i] = x.fre[x.outUsed]
 | |
| 		x.outUsed++
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type ocfbDecrypter struct {
 | |
| 	b       cipher.Block
 | |
| 	fre     []byte
 | |
| 	outUsed int
 | |
| }
 | |
| 
 | |
| // NewOCFBDecrypter returns a cipher.Stream which decrypts data with OpenPGP's
 | |
| // cipher feedback mode using the given cipher.Block. Prefix must be the first
 | |
| // blockSize + 2 bytes of the ciphertext, where blockSize is the cipher.Block's
 | |
| // block size. If an incorrect key is detected then nil is returned. On
 | |
| // successful exit, blockSize+2 bytes of decrypted data are written into
 | |
| // prefix. Resync determines if the "resynchronization step" from RFC 4880,
 | |
| // 13.9 step 7 is performed. Different parts of OpenPGP vary on this point.
 | |
| func NewOCFBDecrypter(block cipher.Block, prefix []byte, resync OCFBResyncOption) cipher.Stream {
 | |
| 	blockSize := block.BlockSize()
 | |
| 	if len(prefix) != blockSize+2 {
 | |
| 		return nil
 | |
| 	}
 | |
| 
 | |
| 	x := &ocfbDecrypter{
 | |
| 		b:       block,
 | |
| 		fre:     make([]byte, blockSize),
 | |
| 		outUsed: 0,
 | |
| 	}
 | |
| 	prefixCopy := make([]byte, len(prefix))
 | |
| 	copy(prefixCopy, prefix)
 | |
| 
 | |
| 	block.Encrypt(x.fre, x.fre)
 | |
| 	for i := 0; i < blockSize; i++ {
 | |
| 		prefixCopy[i] ^= x.fre[i]
 | |
| 	}
 | |
| 
 | |
| 	block.Encrypt(x.fre, prefix[:blockSize])
 | |
| 	prefixCopy[blockSize] ^= x.fre[0]
 | |
| 	prefixCopy[blockSize+1] ^= x.fre[1]
 | |
| 
 | |
| 	if prefixCopy[blockSize-2] != prefixCopy[blockSize] ||
 | |
| 		prefixCopy[blockSize-1] != prefixCopy[blockSize+1] {
 | |
| 		return nil
 | |
| 	}
 | |
| 
 | |
| 	if resync {
 | |
| 		block.Encrypt(x.fre, prefix[2:])
 | |
| 	} else {
 | |
| 		x.fre[0] = prefix[blockSize]
 | |
| 		x.fre[1] = prefix[blockSize+1]
 | |
| 		x.outUsed = 2
 | |
| 	}
 | |
| 	copy(prefix, prefixCopy)
 | |
| 	return x
 | |
| }
 | |
| 
 | |
| func (x *ocfbDecrypter) XORKeyStream(dst, src []byte) {
 | |
| 	for i := 0; i < len(src); i++ {
 | |
| 		if x.outUsed == len(x.fre) {
 | |
| 			x.b.Encrypt(x.fre, x.fre)
 | |
| 			x.outUsed = 0
 | |
| 		}
 | |
| 
 | |
| 		c := src[i]
 | |
| 		dst[i] = x.fre[x.outUsed] ^ src[i]
 | |
| 		x.fre[x.outUsed] = c
 | |
| 		x.outUsed++
 | |
| 	}
 | |
| }
 |