summary refs log tree commit diff
path: root/crypto/src/bcpg/AeadEncDataPacket.cs
blob: 2c7ec97f6f79ff08759757a7c200ab00f2374996 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System;

using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.IO;

namespace Org.BouncyCastle.Bcpg
{
    /**
     * Packet representing AEAD encrypted data. At the moment this appears to exist in the following
     * expired draft only, but it's appearing despite this.
     *
     * @ref https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-rfc4880bis-04#section-5.16
     */
    public class AeadEncDataPacket
        : InputStreamPacket
    {
        private readonly byte m_version;
        private readonly SymmetricKeyAlgorithmTag m_algorithm;
        private readonly AeadAlgorithmTag m_aeadAlgorithm;
        private readonly byte m_chunkSize;
        private readonly byte[] m_iv;

        public AeadEncDataPacket(BcpgInputStream bcpgIn)
            : base(bcpgIn)
        {
            m_version = (byte)bcpgIn.ReadByte();
            if (m_version != 1)
                throw new ArgumentException("wrong AEAD packet version: " + m_version);

            m_algorithm = (SymmetricKeyAlgorithmTag)bcpgIn.ReadByte();
            m_aeadAlgorithm = (AeadAlgorithmTag)bcpgIn.ReadByte();
            m_chunkSize = (byte)bcpgIn.ReadByte();

            m_iv = new byte[GetIVLength(m_aeadAlgorithm)];
            bcpgIn.ReadFully(m_iv);
        }

        public AeadEncDataPacket(SymmetricKeyAlgorithmTag algorithm, AeadAlgorithmTag aeadAlgorithm, int chunkSize,
            byte[] iv)
            : base(null)
        {
            m_version = 1;
            m_algorithm = algorithm;
            m_aeadAlgorithm = aeadAlgorithm;
            m_chunkSize = (byte)chunkSize;
            m_iv = Arrays.Clone(iv);
        }

        public byte Version => m_version;

        public SymmetricKeyAlgorithmTag Algorithm => m_algorithm;

        public AeadAlgorithmTag AeadAlgorithm => m_aeadAlgorithm;

        public int ChunkSize => m_chunkSize;

        public byte[] GetIV()
        {
            return m_iv;
        }

        public static int GetIVLength(AeadAlgorithmTag aeadAlgorithm)
        {
            switch (aeadAlgorithm)
            {
            case AeadAlgorithmTag.Eax:
                return 16;
            case AeadAlgorithmTag.Ocb:
                return 15;
            case AeadAlgorithmTag.Gcm:
                return 12;
            default:
                throw new ArgumentException("unknown mode: " + aeadAlgorithm);
            }
        }
    }
}