Browse Source

padding (may need more work)

Jonathan Turner 9 years ago
parent
commit
eef2311126
2 changed files with 57 additions and 16 deletions
  1. 47 8
      krb5crypto/EncryptionEngine.go
  2. 10 8
      krb5crypto/des3-cbc-sha1-kd.go

+ 47 - 8
krb5crypto/EncryptionEngine.go

@@ -3,6 +3,7 @@ package krb5crypto
 import (
 	"bytes"
 	"encoding/binary"
+	"errors"
 )
 
 type EType interface {
@@ -10,16 +11,16 @@ type EType interface {
 	GetKeyByteSize() int // See protocol key format for defined values
 	StringToKey(string, salt string, s2kparams []byte) (protocolKey []byte)
 	GetDefaultStringToKeyParams() string // s2kparams
-	GetKeySeedBitLength() int // key-generation seed length, k
+	GetKeySeedBitLength() int            // key-generation seed length, k
 	RandomToKey(b []byte) (protocolKey []byte)
-	GetHMACBitLength() int // HMAC output size, h
-	GetMessageBlockByteSize() int // message block size, m
-	Encrypt(key, message []byte) (ct []byte, err error) // E function
+	GetHMACBitLength() int                                      // HMAC output size, h
+	GetMessageBlockByteSize() int                               // message block size, m
+	Encrypt(key, message []byte) (ct []byte, err error)         // E function
 	Decrypt(key, ciphertext []byte) (message []byte, err error) // D function
-	GetCypherBlockBitLength() int // cipher block size, c
-	GetConfounderByteSize() int // This is the same as the cipher block size but in bytes.
-	DeriveKey(protocolKey, usage []byte) (specificKey []byte) // DK
-	DeriveRandom(protocolKey, usage []byte) ([]byte, error) // DR
+	GetCypherBlockBitLength() int                               // cipher block size, c
+	GetConfounderByteSize() int                                 // This is the same as the cipher block size but in bytes.
+	DeriveKey(protocolKey, usage []byte) (specificKey []byte)   // DK
+	DeriveRandom(protocolKey, usage []byte) ([]byte, error)     // DR
 }
 type encryptFunc func([]byte, []byte) ([]byte, error)
 
@@ -55,6 +56,44 @@ func deriveRandom(key, usage []byte, n, k int, encrypt encryptFunc) ([]byte, err
 	return out, nil
 }
 
+
+func pkcs7Pad(b []byte, m int) ([]byte, error) {
+	if m <= 0 {
+		return nil, errors.New("Invalid message block size when padding")
+	}
+	if b == nil || len(b) == 0 {
+		return nil, errors.New("Data not valid to pad: Zero size")
+	}
+	n := m - (len(b) % m)
+	pb := make([]byte, len(b)+n)
+	copy(pb, b)
+	copy(pb[len(b):], bytes.Repeat([]byte{byte(n)}, n))
+	return pb, nil
+}
+
+func pkcs7Unpad(b []byte, m int) ([]byte, error) {
+	if m <= 0 {
+		return nil, errors.New("Invalid message block size when unpadding")
+	}
+	if b == nil || len(b) == 0 {
+		return nil, errors.New("Padded data not valid: Zero size")
+	}
+	if len(b)%m != 0 {
+		return nil, errors.New("Padded data not valid: Not multiple of message block size")
+	}
+	c := b[len(b)-1]
+	n := int(c)
+	if n == 0 || n > len(b) {
+		return nil, errors.New("Padded data not valid: Data may not have been padded")
+	}
+	for i := 0; i < n; i++ {
+		if b[len(b)-n+i] != c {
+			return nil, errors.New("Padded data not valid")
+		}
+	}
+	return b[:len(b)-n], nil
+}
+
 /*
 Key Usage Numbers
 

+ 10 - 8
krb5crypto/des3-cbc-sha1-kd.go

@@ -68,7 +68,8 @@ func (e *Des3CbcSha1Kd) GetHash() hash.Hash {
 }
 
 func (e *Des3CbcSha1Kd) GetMessageBlockByteSize() int {
-	return 8
+	//For traditional CBC mode with padding, it would be the underlying cipher's block size
+	return des.BlockSize
 }
 
 func (e *Des3CbcSha1Kd) GetDefaultStringToKeyParams() string {
@@ -106,7 +107,7 @@ func (e *Des3CbcSha1Kd) DeriveKey(protocolKey, usage []byte) ([]byte, error) {
 	if err != nil {
 		return nil, err
 	}
-	return RandomToKey(r)
+	return RandomToKey(r), nil
 }
 
 func (e *Des3CbcSha1Kd) Encrypt(key, message []byte) ([]byte, error) {
@@ -114,9 +115,8 @@ func (e *Des3CbcSha1Kd) Encrypt(key, message []byte) ([]byte, error) {
 		return nil, fmt.Errorf("Incorrect keysize: expected: %v actual: %v", e.GetKeySeedBitLength(), len(key))
 
 	}
-	if len(message) % des.BlockSize != 0 {
-		return nil, errors.New("Plaintext is not a multiple of the block size. Padding may be needed.")
-
+	if len(message) % e.GetMessageBlockByteSize() != 0 {
+		message, _ = pkcs7Pad(message, e.GetMessageBlockByteSize())
 	}
 
 	block, err := des.NewTripleDESCipher(key)
@@ -128,9 +128,6 @@ func (e *Des3CbcSha1Kd) Encrypt(key, message []byte) ([]byte, error) {
 	//RFC 3961: initial cipher state      All bits zero
 	iv := make([]byte, e.GetConfounderByteSize())
 	//_, err = rand.Read(iv) //Not needed as all bits need to be zero
-	if err != nil {
-		return nil, fmt.Errorf("Error creating random nonce/initial state: %v", err)
-	}
 
 	ct := make([]byte, len(message))
 	mode := cipher.NewCBCEncrypter(block, iv)
@@ -143,6 +140,7 @@ func (e *Des3CbcSha1Kd) Decrypt(key, ciphertext []byte) (message []byte, err err
 		err = fmt.Errorf("Incorrect keysize: expected: %v actual: %v", e.GetKeySeedBitLength(), len(key))
 		return
 	}
+
 	if len(ciphertext) < des.BlockSize || len(ciphertext) % des.BlockSize != 0 {
 		err = errors.New("Ciphertext is not a multiple of the block size.")
 		return
@@ -159,5 +157,9 @@ func (e *Des3CbcSha1Kd) Decrypt(key, ciphertext []byte) (message []byte, err err
 
 	mode := cipher.NewCBCDecrypter(block, iv)
 	mode.CryptBlocks(message, ciphertext)
+	m, er := pkcs7Unpad(message, e.GetMessageBlockByteSize())
+	if er == nil {
+		message = m
+	}
 	return
 }