summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/ssl/sslspec.h
blob: 729ac1006ff07a599f0d40f46f78c56f8275e3de (plain)
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is PRIVATE to SSL.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef __sslspec_h_
#define __sslspec_h_

#include "sslexp.h"
#include "prclist.h"

typedef enum {
    TrafficKeyClearText = 0,
    TrafficKeyEarlyApplicationData = 1,
    TrafficKeyHandshake = 2,
    TrafficKeyApplicationData = 3
} TrafficKeyType;

typedef enum {
    CipherSpecRead,
    CipherSpecWrite,
} CipherSpecDirection;

#define SPEC_DIR(spec) \
    ((spec->direction == CipherSpecRead) ? "read" : "write")

typedef struct ssl3CipherSpecStr ssl3CipherSpec;
typedef struct ssl3BulkCipherDefStr ssl3BulkCipherDef;
typedef struct ssl3MACDefStr ssl3MACDef;
typedef struct ssl3CipherSuiteDefStr ssl3CipherSuiteDef;
typedef PRUint64 sslSequenceNumber;
typedef PRUint16 DTLSEpoch;

/* The SSL bulk cipher definition */
typedef enum {
    cipher_null,
    cipher_rc4,
    cipher_des,
    cipher_3des,
    cipher_aes_128,
    cipher_aes_256,
    cipher_camellia_128,
    cipher_camellia_256,
    cipher_seed,
    cipher_aes_128_gcm,
    cipher_aes_256_gcm,
    cipher_chacha20,
    cipher_missing /* reserved for no such supported cipher */
    /* This enum must match ssl3_cipherName[] in ssl3con.c.  */
} SSL3BulkCipher;

typedef enum {
    type_stream,
    type_block,
    type_aead
} CipherType;

/*
** There are tables of these, all const.
*/
struct ssl3BulkCipherDefStr {
    SSL3BulkCipher cipher;
    SSLCipherAlgorithm calg;
    unsigned int key_size;
    unsigned int secret_key_size;
    CipherType type;
    unsigned int iv_size;
    unsigned int block_size;
    unsigned int tag_size;            /* for AEAD ciphers. */
    unsigned int explicit_nonce_size; /* for AEAD ciphers. */
    SECOidTag oid;
    const char *short_name;
    /* The maximum number of records that can be sent/received with the same
      * symmetric key before the connection will be terminated. */
    PRUint64 max_records;
};

/* to make some of these old enums public without namespace pollution,
** it was necessary to prepend ssl_ to the names.
** These #defines preserve compatibility with the old code here in libssl.
*/
typedef SSLMACAlgorithm SSL3MACAlgorithm;

/*
 * There are tables of these, all const.
 */
struct ssl3MACDefStr {
    SSL3MACAlgorithm mac;
    CK_MECHANISM_TYPE mmech;
    int pad_size;
    int mac_size;
    SECOidTag oid;
};

#define MAX_IV_LENGTH 24

typedef struct {
    PK11SymKey *key;
    PK11SymKey *macKey;
    PK11Context *macContext;
    PRUint8 iv[MAX_IV_LENGTH];
} ssl3KeyMaterial;

typedef SECStatus (*SSLCipher)(void *context,
                               unsigned char *out,
                               int *outlen,
                               int maxout,
                               const unsigned char *in,
                               int inlen);
typedef SECStatus (*SSLAEADCipher)(
    ssl3KeyMaterial *keys,
    PRBool doDecrypt,
    unsigned char *out,
    int *outlen,
    int maxout,
    const unsigned char *in,
    int inlen,
    const unsigned char *additionalData,
    int additionalDataLen);

/* The DTLS anti-replay window in number of packets. Defined here because we
 * need it in the cipher spec. Note that this is a ring buffer but left and
 * right represent the true window, with modular arithmetic used to map them
 * onto the buffer.
 */
#define DTLS_RECVD_RECORDS_WINDOW 1024
#define RECORD_SEQ_MASK ((1ULL << 48) - 1)
#define RECORD_SEQ_MAX RECORD_SEQ_MASK
PR_STATIC_ASSERT(DTLS_RECVD_RECORDS_WINDOW % 8 == 0);

typedef struct DTLSRecvdRecordsStr {
    unsigned char data[DTLS_RECVD_RECORDS_WINDOW / 8];
    sslSequenceNumber left;
    sslSequenceNumber right;
} DTLSRecvdRecords;

/*
 * These are the "specs" used for reading and writing records.  Access to the
 * pointers to these specs, and all the specs' contents (direct and indirect) is
 * protected by the reader/writer lock ss->specLock.
 */
struct ssl3CipherSpecStr {
    PRCList link;
    PRUint8 refCt;

    CipherSpecDirection direction;
    SSL3ProtocolVersion version;
    SSL3ProtocolVersion recordVersion;

    const ssl3BulkCipherDef *cipherDef;
    const ssl3MACDef *macDef;

    SSLCipher cipher;
    SSLAEADCipher aead;
    void *cipherContext;

    PK11SymKey *masterSecret;
    ssl3KeyMaterial keyMaterial;

    DTLSEpoch epoch;
    const char *phase;
    sslSequenceNumber seqNum;
    DTLSRecvdRecords recvdRecords;

    /* The number of 0-RTT bytes that can be sent or received in TLS 1.3. This
     * will be zero for everything but 0-RTT. */
    PRUint32 earlyDataRemaining;
};

typedef void (*sslCipherSpecChangedFunc)(void *arg,
                                         PRBool sending,
                                         ssl3CipherSpec *newSpec);

const ssl3BulkCipherDef *ssl_GetBulkCipherDef(const ssl3CipherSuiteDef *cipher_def);
const ssl3MACDef *ssl_GetMacDefByAlg(SSL3MACAlgorithm mac);
const ssl3MACDef *ssl_GetMacDef(const sslSocket *ss, const ssl3CipherSuiteDef *suiteDef);

ssl3CipherSpec *ssl_CreateCipherSpec(sslSocket *ss, CipherSpecDirection direction);
void ssl_SaveCipherSpec(sslSocket *ss, ssl3CipherSpec *spec);
void ssl_CipherSpecAddRef(ssl3CipherSpec *spec);
void ssl_CipherSpecRelease(ssl3CipherSpec *spec);
void ssl_DestroyCipherSpecs(PRCList *list);
SECStatus ssl_SetupNullCipherSpec(sslSocket *ss, CipherSpecDirection dir);

ssl3CipherSpec *ssl_FindCipherSpecByEpoch(sslSocket *ss,
                                          CipherSpecDirection direction,
                                          DTLSEpoch epoch);
void ssl_CipherSpecReleaseByEpoch(sslSocket *ss, CipherSpecDirection direction,
                                  DTLSEpoch epoch);

#endif /* __sslspec_h_ */