aboutsummaryrefslogtreecommitdiffstats
path: root/docs/development/custom-vectors/cast5
diff options
context:
space:
mode:
Diffstat (limited to 'docs/development/custom-vectors/cast5')
-rw-r--r--docs/development/custom-vectors/cast5/generate_cast5.py58
-rw-r--r--docs/development/custom-vectors/cast5/verify_cast5.go141
2 files changed, 199 insertions, 0 deletions
diff --git a/docs/development/custom-vectors/cast5/generate_cast5.py b/docs/development/custom-vectors/cast5/generate_cast5.py
new file mode 100644
index 00000000..f038825a
--- /dev/null
+++ b/docs/development/custom-vectors/cast5/generate_cast5.py
@@ -0,0 +1,58 @@
+import binascii
+
+from cryptography.hazmat.backends.openssl.backend import backend
+from cryptography.hazmat.primitives.ciphers import base, algorithms, modes
+
+
+def encrypt(mode, key, iv, plaintext):
+ cipher = base.Cipher(
+ algorithms.CAST5(binascii.unhexlify(key)),
+ mode(binascii.unhexlify(iv)),
+ backend
+ )
+ encryptor = cipher.encryptor()
+ ct = encryptor.update(binascii.unhexlify(plaintext))
+ ct += encryptor.finalize()
+ return binascii.hexlify(ct)
+
+
+def build_vectors(mode, filename):
+ vector_file = open(filename, "r")
+
+ count = 0
+ output = []
+ key = None
+ iv = None
+ plaintext = None
+ ct = None
+ for line in vector_file:
+ line = line.strip()
+ if line.startswith("KEY"):
+ if count != 0:
+ output.append("CIPHERTEXT = {}".format(encrypt(mode, key, iv, plaintext)))
+ output.append("\nCOUNT = {}".format(count))
+ count += 1
+ name, key = line.split(" = ")
+ output.append("KEY = {}".format(key))
+ elif line.startswith("IV"):
+ name, iv = line.split(" = ")
+ iv = iv[0:16]
+ output.append("IV = {}".format(iv))
+ elif line.startswith("PLAINTEXT"):
+ name, plaintext = line.split(" = ")
+ output.append("PLAINTEXT = {}".format(plaintext))
+
+ output.append("CIPHERTEXT = {}".format(encrypt(mode, key, iv, plaintext)))
+ return "\n".join(output)
+
+
+def write_file(data, filename):
+ with open(filename, "w") as f:
+ f.write(data)
+
+cbc_path = "tests/hazmat/primitives/vectors/ciphers/AES/CBC/CBCMMT128.rsp"
+write_file(build_vectors(modes.CBC, cbc_path), "cast5-cbc.txt")
+ofb_path = "tests/hazmat/primitives/vectors/ciphers/AES/OFB/OFBMMT128.rsp"
+write_file(build_vectors(modes.OFB, ofb_path), "cast5-ofb.txt")
+cfb_path = "tests/hazmat/primitives/vectors/ciphers/AES/CFB/CFB128MMT128.rsp"
+write_file(build_vectors(modes.CFB, cfb_path), "cast5-cfb.txt")
diff --git a/docs/development/custom-vectors/cast5/verify_cast5.go b/docs/development/custom-vectors/cast5/verify_cast5.go
new file mode 100644
index 00000000..1ea10538
--- /dev/null
+++ b/docs/development/custom-vectors/cast5/verify_cast5.go
@@ -0,0 +1,141 @@
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "code.google.com/p/go.crypto/cast5"
+ "crypto/cipher"
+ "encoding/hex"
+ "fmt"
+ "os"
+ "strings"
+)
+
+func unhexlify(s string) []byte {
+ bytes, err := hex.DecodeString(s)
+ if err != nil {
+ panic(err)
+ }
+ return bytes
+}
+
+type VectorArgs struct {
+ count string
+ key string
+ iv string
+ plaintext string
+ ciphertext string
+}
+
+type VectorVerifier interface {
+ validate(count string, key, iv, plaintext, expected_ciphertext []byte)
+}
+
+type ofbVerifier struct{}
+
+func (o ofbVerifier) validate(count string, key, iv, plaintext, expected_ciphertext []byte) {
+ block, err := cast5.NewCipher(key)
+ if err != nil {
+ panic(err)
+ }
+
+ ciphertext := make([]byte, len(plaintext))
+ stream := cipher.NewOFB(block, iv)
+ stream.XORKeyStream(ciphertext, plaintext)
+
+ if !bytes.Equal(ciphertext, expected_ciphertext) {
+ panic(fmt.Errorf("vector mismatch @ COUNT = %s:\n %s != %s\n",
+ count,
+ hex.EncodeToString(expected_ciphertext),
+ hex.EncodeToString(ciphertext)))
+ }
+}
+
+type cbcVerifier struct{}
+
+func (o cbcVerifier) validate(count string, key, iv, plaintext, expected_ciphertext []byte) {
+ block, err := cast5.NewCipher(key)
+ if err != nil {
+ panic(err)
+ }
+
+ ciphertext := make([]byte, len(plaintext))
+ mode := cipher.NewCBCEncrypter(block, iv)
+ mode.CryptBlocks(ciphertext, plaintext)
+
+ if !bytes.Equal(ciphertext, expected_ciphertext) {
+ panic(fmt.Errorf("vector mismatch @ COUNT = %s:\n %s != %s\n",
+ count,
+ hex.EncodeToString(expected_ciphertext),
+ hex.EncodeToString(ciphertext)))
+ }
+}
+
+type cfbVerifier struct{}
+
+func (o cfbVerifier) validate(count string, key, iv, plaintext, expected_ciphertext []byte) {
+ block, err := cast5.NewCipher(key)
+ if err != nil {
+ panic(err)
+ }
+
+ ciphertext := make([]byte, len(plaintext))
+ stream := cipher.NewCFBEncrypter(block, iv)
+ stream.XORKeyStream(ciphertext, plaintext)
+
+ if !bytes.Equal(ciphertext, expected_ciphertext) {
+ panic(fmt.Errorf("vector mismatch @ COUNT = %s:\n %s != %s\n",
+ count,
+ hex.EncodeToString(expected_ciphertext),
+ hex.EncodeToString(ciphertext)))
+ }
+}
+
+func validateVectors(verifier VectorVerifier, filename string) {
+ vectors, err := os.Open(filename)
+ if err != nil {
+ panic(err)
+ }
+ defer vectors.Close()
+
+ var segments []string
+ var vector *VectorArgs
+
+ scanner := bufio.NewScanner(vectors)
+ for scanner.Scan() {
+ segments = strings.Split(scanner.Text(), " = ")
+
+ switch {
+ case strings.ToUpper(segments[0]) == "COUNT":
+ if vector != nil {
+ verifier.validate(vector.count,
+ unhexlify(vector.key),
+ unhexlify(vector.iv),
+ unhexlify(vector.plaintext),
+ unhexlify(vector.ciphertext))
+ }
+ vector = &VectorArgs{count: segments[1]}
+ case strings.ToUpper(segments[0]) == "IV":
+ vector.iv = segments[1][:16]
+ case strings.ToUpper(segments[0]) == "KEY":
+ vector.key = segments[1]
+ case strings.ToUpper(segments[0]) == "PLAINTEXT":
+ vector.plaintext = segments[1]
+ case strings.ToUpper(segments[0]) == "CIPHERTEXT":
+ vector.ciphertext = segments[1]
+ }
+ }
+
+}
+
+func main() {
+ validateVectors(ofbVerifier{},
+ "tests/hazmat/primitives/vectors/ciphers/CAST5/cast5-ofb.txt")
+ fmt.Println("OFB OK.")
+ validateVectors(cfbVerifier{},
+ "tests/hazmat/primitives/vectors/ciphers/CAST5/cast5-cfb.txt")
+ fmt.Println("CFB OK.")
+ validateVectors(cbcVerifier{},
+ "tests/hazmat/primitives/vectors/ciphers/CAST5/cast5-cbc.txt")
+ fmt.Println("CBC OK.")
+}