Crypt-Bear

 view release on metacpan or  search on metacpan

src/ssl/ssl_engine.c  view on Meta::CPAN

 * -- When accumulating data, oxc points to the start of the data.
 *
 * -- During record sending, oxa (and oxb) point to the next record byte
 * to send, and oxc indicates the end of the current record.
 *
 * Note: sent records must fit within the buffer, since the header is
 * adjusted only when the complete record has been assembled.
 *
 * -- The 'version_out' and 'record_type_out' fields are used to build the
 * record header when the mode is switched to 'sending'.
 *
 *
 * Modes:
 * ------
 *
 * The state register iomode contains one of the following values:
 *
 *  BR_IO_FAILED   I/O failed
 *  BR_IO_IN       input mode
 *  BR_IO_OUT      output mode
 *  BR_IO_INOUT    input/output mode
 *
 * Whether encryption is active on incoming records is indicated by the
 * incrypt flag. For outgoing records, there is no such flag; "encryption"
 * is always considered active, but initially uses functions that do not
 * encrypt anything. The 'incrypt' flag is needed because when there is
 * no active encryption, records larger than the I/O buffer are accepted.
 *
 * Note: we do not support no-encryption modes (MAC only).
 *
 * TODO: implement GCM support
 *
 *
 * Misc:
 * -----
 *
 * 'max_frag_len' is the maximum plaintext size for an outgoing record.
 * By default, it is set to the maximum value that fits in the provided
 * buffers, in the following list: 512, 1024, 2048, 4096, 16384. The
 * caller may change it if needed, but the new value MUST still fit in
 * the buffers, and it MUST be one of the list above for compatibility
 * with the Maximum Fragment Length extension.
 *
 * For incoming records, only the total buffer length and current
 * encryption mode impact the maximum length for incoming records. The
 * 'max_frag_len' value is still adjusted so that records up to that
 * length can be both received and sent.
 *
 *
 * Offsets and lengths:
 * --------------------
 *
 * When sending fragments with TLS-1.1+, the maximum overhead is:
 *   5 bytes for the record header
 *   16 bytes for the explicit IV
 *   48 bytes for the MAC (HMAC/SHA-384)
 *   16 bytes for the padding (AES)
 * so a total of 85 extra bytes. Note that we support block cipher sizes
 * up to 16 bytes (AES) and HMAC output sizes up to 48 bytes (SHA-384).
 *
 * With TLS-1.0 and CBC mode, we apply a 1/n-1 split, for a maximum
 * overhead of:
 *   5 bytes for the first record header
 *   32 bytes for the first record payload (AES-CBC + HMAC/SHA-1)
 *   5 bytes for the second record header
 *   20 bytes for the MAC (HMAC/SHA-1)
 *   16 bytes for the padding (AES)
 *   -1 byte to account for the payload byte in the first record
 * so a total of 77 extra bytes at most, less than the 85 bytes above.
 * Note that with TLS-1.0, the MAC is HMAC with either MD5 or SHA-1, but
 * no other hash function.
 *
 * The implementation does not try to send larger records when the current
 * encryption mode has less overhead.
 *
 * Maximum input record overhead is:
 *   5 bytes for the record header
 *   16 bytes for the explicit IV (TLS-1.1+)
 *   48 bytes for the MAC (HMAC/SHA-384)
 *   256 bytes for the padding
 * so a total of 325 extra bytes.
 *
 * When receiving the next record header, it is written into the buffer
 * bytes 0 to 4 (inclusive). Record data is always written into buf[]
 * starting at offset 5. When encryption is active, the plaintext data
 * may start at a larger offset (e.g. because of an explicit IV).
 */

#define MAX_OUT_OVERHEAD    85
#define MAX_IN_OVERHEAD    325

/* see inner.h */
void
br_ssl_engine_fail(br_ssl_engine_context *rc, int err)
{
	if (rc->iomode != BR_IO_FAILED) {
		rc->iomode = BR_IO_FAILED;
		rc->err = err;
	}
}

/*
 * Adjust registers for a new incoming record.
 */
static void
make_ready_in(br_ssl_engine_context *rc)
{
	rc->ixa = rc->ixb = 0;
	rc->ixc = 5;
	if (rc->iomode == BR_IO_IN) {
		rc->iomode = BR_IO_INOUT;
	}
}

/*
 * Adjust registers for a new outgoing record.
 */
static void
make_ready_out(br_ssl_engine_context *rc)
{
	size_t a, b;

	a = 5;
	b = rc->obuf_len - a;



( run in 0.668 second using v1.01-cache-2.11-cpan-e1769b4cff6 )