Skip to content

Commit ed65759

Browse files
committed
get cipher block size from openssl
1 parent 4a5defa commit ed65759

File tree

4 files changed

+70
-59
lines changed

4 files changed

+70
-59
lines changed

aes.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,8 @@ import "C"
77
import (
88
"crypto/cipher"
99
"errors"
10-
"runtime"
1110
)
1211

13-
const aesBlockSize = 16
14-
1512
type extraModes interface {
1613
// Copied out of crypto/aes/modes.go.
1714
NewCBCEncrypter(iv []byte) cipher.BlockMode
@@ -26,22 +23,21 @@ type extraModes interface {
2623
var _ extraModes = (*aesCipher)(nil)
2724

2825
func NewAESCipher(key []byte) (cipher.Block, error) {
29-
c := &evpCipher{key: make([]byte, len(key))}
30-
copy(c.key, key)
31-
32-
switch len(c.key) * 8 {
26+
var kind cipherKind
27+
switch len(key) * 8 {
3328
case 128:
34-
c.kind = cipherAES128
29+
kind = cipherAES128
3530
case 192:
36-
c.kind = cipherAES192
31+
kind = cipherAES192
3732
case 256:
38-
c.kind = cipherAES256
33+
kind = cipherAES256
3934
default:
4035
return nil, errors.New("crypto/aes: invalid key size")
4136
}
42-
43-
runtime.SetFinalizer(c, (*evpCipher).finalize)
44-
37+
c, err := newEVPCipher(key, kind)
38+
if err != nil {
39+
return nil, err
40+
}
4541
return &aesCipher{c}, nil
4642
}
4743

@@ -55,7 +51,9 @@ type aesCipher struct {
5551
*evpCipher
5652
}
5753

58-
func (c *aesCipher) BlockSize() int { return aesBlockSize }
54+
func (c *aesCipher) BlockSize() int {
55+
return c.blockSize
56+
}
5957

6058
func (c *aesCipher) Encrypt(dst, src []byte) {
6159
c.encrypt(dst, src)

cipher.go

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,23 @@ const (
2424
cipherDES3
2525
)
2626

27+
func (c cipherKind) String() string {
28+
switch c {
29+
case cipherAES128:
30+
return "AES-128"
31+
case cipherAES192:
32+
return "AES-192"
33+
case cipherAES256:
34+
return "AES-256"
35+
case cipherDES:
36+
return "DES"
37+
case cipherDES3:
38+
return "DES3"
39+
default:
40+
panic("unknown cipher kind: " + strconv.Itoa(int(c)))
41+
}
42+
}
43+
2744
type cipherMode int8
2845

2946
const (
@@ -109,10 +126,23 @@ func loadCipher(k cipherKind, mode cipherMode) (cipher C.GO_EVP_CIPHER_PTR) {
109126
}
110127

111128
type evpCipher struct {
112-
key []byte
113-
enc_ctx C.GO_EVP_CIPHER_CTX_PTR
114-
dec_ctx C.GO_EVP_CIPHER_CTX_PTR
115-
kind cipherKind
129+
key []byte
130+
enc_ctx C.GO_EVP_CIPHER_CTX_PTR
131+
dec_ctx C.GO_EVP_CIPHER_CTX_PTR
132+
kind cipherKind
133+
blockSize int
134+
}
135+
136+
func newEVPCipher(key []byte, kind cipherKind) (*evpCipher, error) {
137+
cipher := loadCipher(kind, cipherModeECB)
138+
if cipher == nil {
139+
return nil, errors.New("crypto/cipher: unsupported cipher: " + kind.String())
140+
}
141+
c := &evpCipher{key: make([]byte, len(key)), kind: kind}
142+
copy(c.key, key)
143+
c.blockSize = int(C.go_openssl_EVP_CIPHER_get_block_size(cipher))
144+
runtime.SetFinalizer(c, (*evpCipher).finalize)
145+
return c, nil
116146
}
117147

118148
func (c *evpCipher) finalize() {
@@ -124,28 +154,16 @@ func (c *evpCipher) finalize() {
124154
}
125155
}
126156

127-
func (c *evpCipher) blockSize() int {
128-
switch c.kind {
129-
case cipherAES128, cipherAES192, cipherAES256:
130-
return aesBlockSize
131-
case cipherDES, cipherDES3:
132-
return desBlockSize
133-
default:
134-
panic("openssl: unsupported cipher: " + strconv.Itoa(int(c.kind)))
135-
}
136-
}
137-
138157
func (c *evpCipher) encrypt(dst, src []byte) {
139-
blockSize := c.blockSize()
140-
if len(src) < blockSize {
158+
if len(src) < c.blockSize {
141159
panic("crypto/cipher: input not full block")
142160
}
143-
if len(dst) < blockSize {
161+
if len(dst) < c.blockSize {
144162
panic("crypto/cipher: output not full block")
145163
}
146164
// Only check for overlap between the parts of src and dst that will actually be used.
147165
// This matches Go standard library behavior.
148-
if inexactOverlap(dst[:blockSize], src[:blockSize]) {
166+
if inexactOverlap(dst[:c.blockSize], src[:c.blockSize]) {
149167
panic("crypto/cipher: invalid buffer overlap")
150168
}
151169
if c.enc_ctx == nil {
@@ -156,23 +174,22 @@ func (c *evpCipher) encrypt(dst, src []byte) {
156174
}
157175
}
158176

159-
if C.go_openssl_EVP_EncryptUpdate_wrapper(c.enc_ctx, base(dst), base(src), C.int(blockSize)) != 1 {
177+
if C.go_openssl_EVP_EncryptUpdate_wrapper(c.enc_ctx, base(dst), base(src), C.int(c.blockSize)) != 1 {
160178
panic("crypto/cipher: EncryptUpdate failed")
161179
}
162180
runtime.KeepAlive(c)
163181
}
164182

165183
func (c *evpCipher) decrypt(dst, src []byte) {
166-
blockSize := c.blockSize()
167-
if len(src) < blockSize {
184+
if len(src) < c.blockSize {
168185
panic("crypto/cipher: input not full block")
169186
}
170-
if len(dst) < blockSize {
187+
if len(dst) < c.blockSize {
171188
panic("crypto/cipher: output not full block")
172189
}
173190
// Only check for overlap between the parts of src and dst that will actually be used.
174191
// This matches Go standard library behavior.
175-
if inexactOverlap(dst[:blockSize], src[:blockSize]) {
192+
if inexactOverlap(dst[:c.blockSize], src[:c.blockSize]) {
176193
panic("crypto/cipher: invalid buffer overlap")
177194
}
178195
if c.dec_ctx == nil {
@@ -186,7 +203,7 @@ func (c *evpCipher) decrypt(dst, src []byte) {
186203
}
187204
}
188205

189-
C.go_openssl_EVP_DecryptUpdate_wrapper(c.dec_ctx, base(dst), base(src), C.int(blockSize))
206+
C.go_openssl_EVP_DecryptUpdate_wrapper(c.dec_ctx, base(dst), base(src), C.int(c.blockSize))
190207
runtime.KeepAlive(c)
191208
}
192209

@@ -237,7 +254,7 @@ func (c *evpCipher) newCBC(iv []byte, encrypt bool) cipher.BlockMode {
237254
if err != nil {
238255
panic(err)
239256
}
240-
x := &cipherCBC{ctx: ctx, blockSize: c.blockSize()}
257+
x := &cipherCBC{ctx: ctx, blockSize: c.blockSize}
241258
runtime.SetFinalizer(x, (*cipherCBC).finalize)
242259
if C.go_openssl_EVP_CIPHER_CTX_set_padding(x.ctx, 0) != 1 {
243260
panic("cipher: unable to set padding")
@@ -298,7 +315,7 @@ type noGCM struct {
298315
}
299316

300317
func (g *noGCM) BlockSize() int {
301-
return g.blockSize()
318+
return g.blockSize
302319
}
303320

304321
func (g *noGCM) Encrypt(dst, src []byte) {
@@ -328,7 +345,7 @@ func (c *evpCipher) newGCM(tls bool) (cipher.AEAD, error) {
328345
if err != nil {
329346
return nil, err
330347
}
331-
g := &cipherGCM{ctx: ctx, tls: tls, blockSize: c.blockSize()}
348+
g := &cipherGCM{ctx: ctx, tls: tls, blockSize: c.blockSize}
332349
runtime.SetFinalizer(g, (*cipherGCM).finalize)
333350
return g, nil
334351
}
@@ -455,7 +472,7 @@ func sliceForAppend(in []byte, n int) (head, tail []byte) {
455472
func newCipherCtx(kind cipherKind, mode cipherMode, encrypt int, key, iv []byte) (C.GO_EVP_CIPHER_CTX_PTR, error) {
456473
cipher := loadCipher(kind, mode)
457474
if cipher == nil {
458-
panic("openssl: unsupported cipher: " + strconv.Itoa(int(kind)))
475+
panic("crypto/cipher: unsupported cipher: " + kind.String())
459476
}
460477
ctx := C.go_openssl_EVP_CIPHER_CTX_new()
461478
if ctx == nil {

des.go

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,8 @@ import "C"
77
import (
88
"crypto/cipher"
99
"errors"
10-
"runtime"
1110
)
1211

13-
const desBlockSize = 8
14-
1512
// SupportsDESCipher returns true if NewDESCipher is supported.
1613
func SupportsDESCipher() bool {
1714
// True for stock OpenSSL 1.
@@ -27,28 +24,24 @@ func SupportsTripleDESCipher() bool {
2724
}
2825

2926
func NewDESCipher(key []byte) (cipher.Block, error) {
30-
if !SupportsDESCipher() {
31-
return nil, errors.New("crypto/des: not supported")
32-
}
3327
if len(key) != 8 {
3428
return nil, errors.New("crypto/des: invalid key size")
3529
}
36-
c := &evpCipher{key: make([]byte, len(key)), kind: cipherDES}
37-
copy(c.key, key)
38-
runtime.SetFinalizer(c, (*evpCipher).finalize)
30+
c, err := newEVPCipher(key, cipherDES)
31+
if err != nil {
32+
return nil, err
33+
}
3934
return &desCipher{c}, nil
4035
}
4136

4237
func NewTripleDESCipher(key []byte) (cipher.Block, error) {
43-
if !SupportsTripleDESCipher() {
44-
return nil, errors.New("crypto/des: not supported")
45-
}
4638
if len(key) != 24 {
4739
return nil, errors.New("crypto/des: invalid key size")
4840
}
49-
c := &evpCipher{key: make([]byte, len(key)), kind: cipherDES3}
50-
copy(c.key, key)
51-
runtime.SetFinalizer(c, (*evpCipher).finalize)
41+
c, err := newEVPCipher(key, cipherDES3)
42+
if err != nil {
43+
return nil, err
44+
}
5245
return &desCipher{c}, nil
5346
}
5447

@@ -63,7 +56,9 @@ type desCipher struct {
6356
*evpCipher
6457
}
6558

66-
func (c *desCipher) BlockSize() int { return desBlockSize }
59+
func (c *desCipher) BlockSize() int {
60+
return c.blockSize
61+
}
6762

6863
func (c *desCipher) Encrypt(dst, src []byte) {
6964
c.encrypt(dst, src)

shims.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_ecb, (void), ()) \
246246
DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_cbc, (void), ()) \
247247
DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_ede3_ecb, (void), ()) \
248248
DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_ede3_cbc, (void), ()) \
249+
DEFINEFUNC_RENAMED_3_0(int, EVP_CIPHER_get_block_size, EVP_CIPHER_block_size, (const GO_EVP_CIPHER_PTR cipher), (cipher)) \
249250
DEFINEFUNC(void, EVP_CIPHER_CTX_free, (GO_EVP_CIPHER_CTX_PTR arg0), (arg0)) \
250251
DEFINEFUNC(int, EVP_CIPHER_CTX_ctrl, (GO_EVP_CIPHER_CTX_PTR ctx, int type, int arg, void *ptr), (ctx, type, arg, ptr)) \
251252
DEFINEFUNC(GO_EVP_PKEY_PTR, EVP_PKEY_new, (void), ()) \

0 commit comments

Comments
 (0)