2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 internal static void Enc16be(int x, byte[] buf, int off)
34 buf[off + 0] = (byte)(x >> 8);
35 buf[off + 1] = (byte)x;
38 internal static void Enc24be(int x, byte[] buf, int off)
40 buf[off + 0] = (byte)(x >> 16);
41 buf[off + 1] = (byte)(x >> 8);
42 buf[off + 2] = (byte)x;
45 internal static void Enc32be(uint x, byte[] buf, int off)
47 buf[off + 0] = (byte)(x >> 24);
48 buf[off + 1] = (byte)(x >> 16);
49 buf[off + 2] = (byte)(x >> 8);
50 buf[off + 3] = (byte)x;
53 internal static void Enc64be(ulong x, byte[] buf, int off)
55 for (int i = 0; i < 8; i ++) {
56 buf[off + 7 - i] = (byte)x;
61 internal static int Dec16be(byte[] buf, int off)
63 return (buf[off + 0] << 8)
67 internal static int Dec24be(byte[] buf, int off)
69 return (buf[off + 0] << 16)
74 internal static uint Dec32be(byte[] buf, int off)
76 return ((uint)buf[off + 0] << 24)
77 | ((uint)buf[off + 1] << 16)
78 | ((uint)buf[off + 2] << 8)
82 internal static ulong Dec64be(byte[] buf, int off)
85 for (int i = 0; i < 8; i ++) {
86 x = (x << 8) | buf[off + i];
91 internal static void Write16(Stream s, int x)
93 s.WriteByte((byte)(x >> 8));
97 internal static void Write24(Stream s, int x)
99 s.WriteByte((byte)(x >> 16));
100 s.WriteByte((byte)(x >> 8));
101 s.WriteByte((byte)x);
105 * Write a 5-byte record header at the specified offset.
107 internal static void WriteHeader(int recordType, int version,
108 int length, byte[] buf, int off)
110 buf[off] = (byte)recordType;
111 IO.Enc16be(version, buf, off + 1);
112 IO.Enc16be(length, buf, off + 3);
116 * Read all requested bytes. Fail on unexpected EOF, unless
117 * 'eof' is true, in which case an EOF is acceptable at the
118 * very beginning (i.e. no byte read at all).
120 * Returned value is true, unless there was an EOF at the
121 * start and 'eof' is true, in which case returned value is
124 internal static bool ReadAll(Stream s, byte[] buf, bool eof)
126 return ReadAll(s, buf, 0, buf.Length, eof);
130 * Read all requested bytes. Fail on unexpected EOF, unless
131 * 'eof' is true, in which case an EOF is acceptable at the
132 * very beginning (i.e. no byte read at all).
134 * Returned value is true, unless there was an EOF at the
135 * start and 'eof' is true, in which case returned value is
138 internal static bool ReadAll(Stream s,
139 byte[] buf, int off, int len, bool eof)
143 int rlen = s.Read(buf, off + tlen, len - tlen);
145 if (eof && tlen == 0) {
148 throw new SSLException("Unexpected EOF");
156 * Compare two arrays of bytes for equality.
158 internal static bool Eq(byte[] a, byte[] b)
160 return EqCT(a, b) != 0;
164 * Compare two arrays of bytes for equality. This is constant-time
165 * if both arrays have the same length. Returned value is 0xFFFFFFFF
166 * on equality, 0 otherwise.
168 internal static uint EqCT(byte[] a, byte[] b)
175 for (int i = 0; i < n; i ++) {
178 return ~(uint)((z | -z) >> 31);
182 * Duplicate an array of bytes. null is duplicated into null.
184 internal static byte[] CopyBlob(byte[] x)
189 byte[] y = new byte[x.Length];
190 Array.Copy(x, 0, y, 0, x.Length);