ivcipher.bend

bend-osdev-aead@0.1.0.0 · 37 lines · 6 definitions

1# Ciphers with an IV, of the shape authenc.bend and essiv.bend take (a key
2# schedule, an IV and bytes): any block cipher of the crypto package's
3# block-cipher interface in CBC (crypto's modes.bend, NIST SP 800-38A),
4# whole blocks only (the kernel's cbc) or PKCS #7 padded (RFC 5652, section
5# 6.3; cipher-modes' pkcs7.bend), as draft-mcgrew-aead-aes-cbc-hmac-sha2
6# uses it.
7#
8# Each is ~enc and ~dec for those files, for example AES-CBC:
9#   ~AdCbc.encrypt(~X.CmAesKey, ~M.CmBlock, ~16n, ~X.CmAes.encrypt,
10#     ~CM.CrBlk128.xor, ~CM.CrBlk128.of_octets, ~CM.CrBlk128.to_octets)
11import Base
12import bend-osdev-bytes@0.1.0.0/bytes.bend as B
13import bend-osdev-cipher-modes@0.1.0.0/pkcs7.bend as P7
14import bend-osdev-crypto@0.1.0.0/crypto.bend as Cr
15import bend-osdev-crypto@0.1.0.0/modes.bend as Md
16import bend-osdev-crypto@0.1.0.0/inst_cm.bend as CM
17
18# CBC, whole blocks (CrNotBlockMultiple otherwise), a one-block IV
19def AdCbc.encrypt(~K: Data, ~Blk: Data, ~bsize: Nat, ~enc: K -> Blk -> Blk, ~bxor: Blk -> Blk -> Blk, ~blk_of: B.Octets -> Maybe<&2, Blk>, ~blk_to: Blk -> B.Octets, k: K, iv: B.Octets, m: B.Octets) -> Result<&2, &2, Cr.CrError, B.Octets>:
20  Md.CrCbc.encrypt(~K, ~Blk, ~bsize, ~enc, ~bxor, ~blk_of, ~blk_to, k, iv, m)
21
22def AdCbc.decrypt(~K: Data, ~Blk: Data, ~bsize: Nat, ~dec: K -> Blk -> Blk, ~bxor: Blk -> Blk -> Blk, ~blk_of: B.Octets -> Maybe<&2, Blk>, ~blk_to: Blk -> B.Octets, k: K, iv: B.Octets, c: B.Octets) -> Result<&2, &2, Cr.CrError, B.Octets>:
23  Md.CrCbc.decrypt(~K, ~Blk, ~bsize, ~dec, ~bxor, ~blk_of, ~blk_to, k, iv, c)
24
25def ad.cbc.encrypt_padded(~K: Data, ~Blk: Data, ~bsize: Nat, ~enc: K -> Blk -> Blk, ~bxor: Blk -> Blk -> Blk, ~blk_of: B.Octets -> Maybe<&2, Blk>, ~blk_to: Blk -> B.Octets, +k: K, +iv: B.Octets, m: B.Octets) -> Result<&2, &2, Cr.CrError, B.Octets>:
26  Result.bind(&2, &2, Cr.CrError, B.Octets, B.Octets, CM.CrCm.lift(~B.Octets, P7.Pkcs7.pad(bsize, m)), x => Md.CrCbc.encrypt(~K, ~Blk, ~bsize, ~enc, ~bxor, ~blk_of, ~blk_to, k, iv, x))
27
28def ad.cbc.decrypt_padded(~K: Data, ~Blk: Data, ~bsize: Nat, ~dec: K -> Blk -> Blk, ~bxor: Blk -> Blk -> Blk, ~blk_of: B.Octets -> Maybe<&2, Blk>, ~blk_to: Blk -> B.Octets, +k: K, +iv: B.Octets, c: B.Octets) -> Result<&2, &2, Cr.CrError, B.Octets>:
29  Result.bind(&2, &2, Cr.CrError, B.Octets, B.Octets, Md.CrCbc.decrypt(~K, ~Blk, ~bsize, ~dec, ~bxor, ~blk_of, ~blk_to, k, iv, c), x => CM.CrCm.lift(~B.Octets, P7.Pkcs7.unpad(bsize, x)))
30
31# CBC of the PKCS #7 padding of m, any length
32def AdCbc.encrypt_padded(~K: Data, ~Blk: Data, ~bsize: Nat, ~enc: K -> Blk -> Blk, ~bxor: Blk -> Blk -> Blk, ~blk_of: B.Octets -> Maybe<&2, Blk>, ~blk_to: Blk -> B.Octets, k: K, iv: B.Octets, m: B.Octets) -> Result<&2, &2, Cr.CrError, B.Octets>:
33  ad.cbc.encrypt_padded(~K, ~Blk, ~bsize, ~enc, ~bxor, ~blk_of, ~blk_to, k, iv, m)
34
35# the padding removed after CBC decryption (CrBadPadding)
36def AdCbc.decrypt_padded(~K: Data, ~Blk: Data, ~bsize: Nat, ~dec: K -> Blk -> Blk, ~bxor: Blk -> Blk -> Blk, ~blk_of: B.Octets -> Maybe<&2, Blk>, ~blk_to: Blk -> B.Octets, k: K, iv: B.Octets, c: B.Octets) -> Result<&2, &2, Cr.CrError, B.Octets>:
37  ad.cbc.decrypt_padded(~K, ~Blk, ~bsize, ~dec, ~bxor, ~blk_of, ~blk_to, k, iv, c)