-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into topic/rewrite
- Loading branch information
Showing
75 changed files
with
306 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
// -*- go -*- | ||
// | ||
// Copyright (c) 2024 Markku Rossi | ||
// | ||
// All rights reserved. | ||
// | ||
|
||
// Package cts implements the ciphertext stealing (CTS) mode of | ||
// operation for block ciphers. The implementation uses the CTS-3 | ||
// (Kerberos) variant for formatting the cipher text. | ||
package cts | ||
|
||
import ( | ||
"crypto/aes" | ||
) | ||
|
||
// EncryptAES128 encrypts the data in AES-CTS mode. The key specifies | ||
// the AES encryption key and iv is a random initialization vector. | ||
func EncryptAES128(key [16]byte, iv [aes.BlockSize]byte, data []byte) []byte { | ||
numBlocks := len(data) / aes.BlockSize | ||
tail := len(data) % aes.BlockSize | ||
|
||
if tail != 0 { | ||
numBlocks++ | ||
} else { | ||
tail = aes.BlockSize | ||
} | ||
if numBlocks < 2 { | ||
panic("cts.EncryptAES128: input must be at least 2 block") | ||
} | ||
var block [aes.BlockSize]byte | ||
block = memcpy(block, 0, iv, 0) | ||
|
||
var plain [aes.BlockSize]byte | ||
var cipher [len(data)]byte | ||
|
||
// Standard CBC for the first numBlocks-1 blocks. | ||
for i := 0; i < numBlocks-1; i++ { | ||
plain = memcpy(plain, 0, data, i*aes.BlockSize) | ||
for j := 0; j < aes.BlockSize; j++ { | ||
plain[j] ^= block[j] | ||
} | ||
block = aes.EncryptBlock(key, plain) | ||
if i < numBlocks-2 { | ||
// Store standard CBC output block. | ||
cipher = memcpy(cipher, i*aes.BlockSize, block, 0) | ||
} else { | ||
// Store last ciphertext block. | ||
cipher = memcpy(cipher, (numBlocks-1)*aes.BlockSize, block, 0) | ||
} | ||
} | ||
|
||
// Create last input block. | ||
plain = memcpy(plain, 0, data, (numBlocks-1)*aes.BlockSize) | ||
for i := tail; i < aes.BlockSize; i++ { | ||
plain[i] = 0 | ||
} | ||
for j := 0; j < aes.BlockSize; j++ { | ||
plain[j] ^= block[j] | ||
} | ||
block = aes.EncryptBlock(key, plain) | ||
cipher = memcpy(cipher, (numBlocks-2)*aes.BlockSize, block, 0) | ||
|
||
return cipher | ||
} | ||
|
||
// DecryptAES128 decrypts the data that is encrypted in AES-CTS | ||
// mode. The key specifies the AES encryption key and iv is the random | ||
// initialization vector used in encryption. | ||
func DecryptAES128(key [16]byte, iv [aes.BlockSize]byte, data []byte) []byte { | ||
numBlocks := len(data) / aes.BlockSize | ||
tail := len(data) % aes.BlockSize | ||
|
||
if tail != 0 { | ||
numBlocks++ | ||
} else { | ||
tail = aes.BlockSize | ||
} | ||
|
||
if numBlocks < 2 { | ||
panic("cts.DecryptAES128: input must be at least 2 blocks") | ||
} | ||
var block [aes.BlockSize]byte | ||
var cipher [aes.BlockSize]byte | ||
var tmp2 [aes.BlockSize]byte | ||
var plain [len(data)]byte | ||
|
||
// Standard CBC for the first numBlocks-2 blocks. | ||
for i := 0; i < numBlocks-2; i++ { | ||
cipher = memcpy(cipher, 0, data, i*aes.Blocks) | ||
block = aes.DecryptBlock(key, cipher) | ||
for j := 0; j < aes.BlockSize; j++ { | ||
block[j] ^= iv[j] | ||
} | ||
plain = memcpy(plain, i*aes.BlockSize, block, 0) | ||
iv = memcpy(iv, 0, cipher, 0) | ||
} | ||
|
||
// Decrypt second-to-last cipher block. | ||
cipher = memcpy(cipher, 0, data, (numBlocks-2)*aes.BlockSize) | ||
tmp := aes.DecryptBlock(key, cipher) | ||
|
||
// Create padded last cipher block. | ||
tmp2 = memcpy(tmp2, 0, data, (numBlocks-1)*aes.BlockSize) | ||
tmp2 = memcpy(tmp2, tail, tmp, tail) | ||
|
||
// Decrypt second-to-last block. | ||
block = aes.DecryptBlock(key, tmp2) | ||
for j := 0; j < aes.BlockSize; j++ { | ||
block[j] ^= iv[j] | ||
} | ||
plain = memcpy(plain, (numBlocks-2)*aes.BlockSize, block, 0) | ||
iv = memcpy(iv, 0, tmp2, 0) | ||
|
||
// Finalize last block. | ||
for j := 0; j < aes.BlockSize; j++ { | ||
tmp[j] ^= iv[j] | ||
} | ||
plain = memcpy(plain, (numBlocks-1)*aes.BlockSize, tmp, 0) | ||
|
||
return plain | ||
} | ||
|
||
func memcpy(dst []byte, dstOfs int, src []byte, srcOfs int) []byte { | ||
for i := 0; srcOfs+i < len(src) && dstOfs+i < len(dst); i++ { | ||
dst[dstOfs+i] = src[srcOfs+i] | ||
} | ||
return dst | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// -*- go -*- | ||
|
||
package main | ||
|
||
import ( | ||
"crypto/cipher/cts" | ||
) | ||
|
||
// @Hex | ||
// @LSB | ||
// @Test 0xc6353568f2bf8cb4d8a580362da7ff7f97 _ = 0x4920776f756c64206c696b652074686520 | ||
func main(data []byte, e []byte) []byte { | ||
key := []byte{ | ||
0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, | ||
0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69, | ||
} | ||
var iv [16]byte | ||
return cts.DecryptAES128(key, iv, data) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// -*- go -*- | ||
|
||
package main | ||
|
||
import ( | ||
"crypto/cipher/cts" | ||
) | ||
|
||
// @Hex | ||
// @LSB | ||
// @Test 0x4920776f756c64206c696b652074686520 _ = 0xc6353568f2bf8cb4d8a580362da7ff7f97 | ||
func main(data []byte, e []byte) []byte { | ||
key := []byte{ | ||
0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, | ||
0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69, | ||
} | ||
var iv [16]byte | ||
return cts.EncryptAES128(key, iv, data) | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Oops, something went wrong.