Skip to content

Commit

Permalink
Implemented cts.DecryptAES128().
Browse files Browse the repository at this point in the history
  • Loading branch information
markkurossi committed Jun 13, 2024
1 parent a52599e commit 7af5e4c
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
59 changes: 58 additions & 1 deletion pkg/crypto/cipher/cts/cts.mpcl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func EncryptAES128(key [16]byte, iv [aes.BlockSize]byte, data []byte) []byte {
tail = aes.BlockSize
}
if numBlocks < 2 {
panic("ctx.EncryptAES128: input must be at least 2 block")
panic("cts.EncryptAES128: input must be at least 2 block")
}
var block [aes.BlockSize]byte
block = memcpy(block, 0, iv, 0)
Expand Down Expand Up @@ -64,6 +64,63 @@ func EncryptAES128(key [16]byte, iv [aes.BlockSize]byte, data []byte) []byte {
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]
Expand Down
19 changes: 19 additions & 0 deletions testsuite/crypto/cipher/cts/aes128_cts_dec.mpcl
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)
}
File renamed without changes.

0 comments on commit 7af5e4c

Please sign in to comment.