Home | History | Annotate | Line # | Download | only in ciphers
      1      1.1  christos /*
      2      1.1  christos  * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
      3      1.1  christos  *
      4      1.1  christos  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5      1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6      1.1  christos  * in the file LICENSE in the source distribution or at
      7      1.1  christos  * https://www.openssl.org/source/license.html
      8      1.1  christos  */
      9      1.1  christos 
     10      1.1  christos #include <assert.h>
     11      1.1  christos /* For SSL3_VERSION, TLS1_VERSION etc */
     12      1.1  christos #include <openssl/prov_ssl.h>
     13      1.1  christos #include <openssl/rand.h>
     14      1.1  christos #include <openssl/proverr.h>
     15      1.1  christos #include "internal/constant_time.h"
     16      1.1  christos #include "internal/ssl3_cbc.h"
     17      1.1  christos #include "ciphercommon_local.h"
     18      1.1  christos 
     19      1.1  christos /*
     20      1.1  christos  * Fills a single block of buffered data from the input, and returns the amount
     21      1.1  christos  * of data remaining in the input that is a multiple of the blocksize. The buffer
     22      1.1  christos  * is only filled if it already has some data in it, isn't full already or we
     23      1.1  christos  * don't have at least one block in the input.
     24      1.1  christos  *
     25      1.1  christos  * buf: a buffer of blocksize bytes
     26      1.1  christos  * buflen: contains the amount of data already in buf on entry. Updated with the
     27      1.1  christos  *         amount of data in buf at the end. On entry *buflen must always be
     28      1.1  christos  *         less than the blocksize
     29      1.1  christos  * blocksize: size of a block. Must be greater than 0 and a power of 2
     30      1.1  christos  * in: pointer to a pointer containing the input data
     31      1.1  christos  * inlen: amount of input data available
     32      1.1  christos  *
     33      1.1  christos  * On return buf is filled with as much data as possible up to a full block,
     34      1.1  christos  * *buflen is updated containing the amount of data in buf. *in is updated to
     35      1.1  christos  * the new location where input data should be read from, *inlen is updated with
     36      1.1  christos  * the remaining amount of data in *in. Returns the largest value <= *inlen
     37      1.1  christos  * which is a multiple of the blocksize.
     38      1.1  christos  */
     39      1.1  christos size_t ossl_cipher_fillblock(unsigned char *buf, size_t *buflen,
     40  1.1.1.2  christos     size_t blocksize,
     41  1.1.1.2  christos     const unsigned char **in, size_t *inlen)
     42      1.1  christos {
     43      1.1  christos     size_t blockmask = ~(blocksize - 1);
     44      1.1  christos     size_t bufremain = blocksize - *buflen;
     45      1.1  christos 
     46      1.1  christos     assert(*buflen <= blocksize);
     47      1.1  christos     assert(blocksize > 0 && (blocksize & (blocksize - 1)) == 0);
     48      1.1  christos 
     49      1.1  christos     if (*inlen < bufremain)
     50      1.1  christos         bufremain = *inlen;
     51      1.1  christos     memcpy(buf + *buflen, *in, bufremain);
     52      1.1  christos     *in += bufremain;
     53      1.1  christos     *inlen -= bufremain;
     54      1.1  christos     *buflen += bufremain;
     55      1.1  christos 
     56      1.1  christos     return *inlen & blockmask;
     57      1.1  christos }
     58      1.1  christos 
     59      1.1  christos /*
     60      1.1  christos  * Fills the buffer with trailing data from an encryption/decryption that didn't
     61      1.1  christos  * fit into a full block.
     62      1.1  christos  */
     63      1.1  christos int ossl_cipher_trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
     64  1.1.1.2  christos     const unsigned char **in, size_t *inlen)
     65      1.1  christos {
     66      1.1  christos     if (*inlen == 0)
     67      1.1  christos         return 1;
     68      1.1  christos 
     69      1.1  christos     if (*buflen + *inlen > blocksize) {
     70      1.1  christos         ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
     71      1.1  christos         return 0;
     72      1.1  christos     }
     73      1.1  christos 
     74      1.1  christos     memcpy(buf + *buflen, *in, *inlen);
     75      1.1  christos     *buflen += *inlen;
     76      1.1  christos     *inlen = 0;
     77      1.1  christos 
     78      1.1  christos     return 1;
     79      1.1  christos }
     80      1.1  christos 
     81      1.1  christos /* Pad the final block for encryption */
     82      1.1  christos void ossl_cipher_padblock(unsigned char *buf, size_t *buflen, size_t blocksize)
     83      1.1  christos {
     84      1.1  christos     size_t i;
     85      1.1  christos     unsigned char pad = (unsigned char)(blocksize - *buflen);
     86      1.1  christos 
     87      1.1  christos     for (i = *buflen; i < blocksize; i++)
     88      1.1  christos         buf[i] = pad;
     89      1.1  christos }
     90      1.1  christos 
     91      1.1  christos int ossl_cipher_unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize)
     92      1.1  christos {
     93      1.1  christos     size_t pad, i;
     94      1.1  christos     size_t len = *buflen;
     95      1.1  christos 
     96      1.1  christos     if (len != blocksize) {
     97      1.1  christos         ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
     98      1.1  christos         return 0;
     99      1.1  christos     }
    100      1.1  christos 
    101      1.1  christos     /*
    102      1.1  christos      * The following assumes that the ciphertext has been authenticated.
    103      1.1  christos      * Otherwise it provides a padding oracle.
    104      1.1  christos      */
    105      1.1  christos     pad = buf[blocksize - 1];
    106      1.1  christos     if (pad == 0 || pad > blocksize) {
    107      1.1  christos         ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT);
    108      1.1  christos         return 0;
    109      1.1  christos     }
    110      1.1  christos     for (i = 0; i < pad; i++) {
    111      1.1  christos         if (buf[--len] != pad) {
    112      1.1  christos             ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT);
    113      1.1  christos             return 0;
    114      1.1  christos         }
    115      1.1  christos     }
    116      1.1  christos     *buflen = len;
    117      1.1  christos     return 1;
    118      1.1  christos }
    119      1.1  christos 
    120      1.1  christos /*-
    121      1.1  christos  * ossl_cipher_tlsunpadblock removes the CBC padding from the decrypted, TLS, CBC
    122      1.1  christos  * record in constant time. Also removes the MAC from the record in constant
    123      1.1  christos  * time.
    124      1.1  christos  *
    125      1.1  christos  * libctx: Our library context
    126      1.1  christos  * tlsversion: The TLS version in use, e.g. SSL3_VERSION, TLS1_VERSION, etc
    127      1.1  christos  * buf: The decrypted TLS record data
    128      1.1  christos  * buflen: The length of the decrypted TLS record data. Updated with the new
    129      1.1  christos  *         length after the padding is removed
    130      1.1  christos  * block_size: the block size of the cipher used to encrypt the record.
    131      1.1  christos  * mac: Location to store the pointer to the MAC
    132      1.1  christos  * alloced: Whether the MAC is stored in a newly allocated buffer, or whether
    133      1.1  christos  *          *mac points into *buf
    134      1.1  christos  * macsize: the size of the MAC inside the record (or 0 if there isn't one)
    135      1.1  christos  * aead: whether this is an aead cipher
    136      1.1  christos  * returns:
    137      1.1  christos  *   0: (in non-constant time) if the record is publicly invalid.
    138      1.1  christos  *   1: (in constant time) Record is publicly valid. If padding is invalid then
    139      1.1  christos  *      the mac is random
    140      1.1  christos  */
    141      1.1  christos int ossl_cipher_tlsunpadblock(OSSL_LIB_CTX *libctx, unsigned int tlsversion,
    142  1.1.1.2  christos     unsigned char *buf, size_t *buflen,
    143  1.1.1.2  christos     size_t blocksize,
    144  1.1.1.2  christos     unsigned char **mac, int *alloced, size_t macsize,
    145  1.1.1.2  christos     int aead)
    146      1.1  christos {
    147      1.1  christos     int ret;
    148      1.1  christos 
    149      1.1  christos     switch (tlsversion) {
    150      1.1  christos     case SSL3_VERSION:
    151      1.1  christos         return ssl3_cbc_remove_padding_and_mac(buflen, *buflen, buf, mac,
    152  1.1.1.2  christos             alloced, blocksize, macsize,
    153  1.1.1.2  christos             libctx);
    154      1.1  christos 
    155      1.1  christos     case TLS1_2_VERSION:
    156      1.1  christos     case DTLS1_2_VERSION:
    157      1.1  christos     case TLS1_1_VERSION:
    158      1.1  christos     case DTLS1_VERSION:
    159      1.1  christos     case DTLS1_BAD_VER:
    160      1.1  christos         /* Remove the explicit IV */
    161      1.1  christos         buf += blocksize;
    162      1.1  christos         *buflen -= blocksize;
    163      1.1  christos         /* Fall through */
    164      1.1  christos     case TLS1_VERSION:
    165      1.1  christos         ret = tls1_cbc_remove_padding_and_mac(buflen, *buflen, buf, mac,
    166  1.1.1.2  christos             alloced, blocksize, macsize,
    167  1.1.1.2  christos             aead, libctx);
    168      1.1  christos         return ret;
    169      1.1  christos 
    170      1.1  christos     default:
    171      1.1  christos         return 0;
    172      1.1  christos     }
    173      1.1  christos }
    174