Skip to main content
  • Home
  • login
  • Browse the archive

    swh mirror partner logo
swh logo
SoftwareHeritage
Software
Heritage
Mirror
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

swh:1:snp:dc2a5002442a00b1c0eda7c65d04ea7455e166cd
  • Code
  • Branches (204)
  • Releases (207)
    • Branches
    • Releases
    • HEAD
    • refs/heads/OpenSSL-engine-0_9_6-stable
    • refs/heads/OpenSSL-fips-0_9_7-stable
    • refs/heads/OpenSSL-fips-0_9_8-stable
    • refs/heads/OpenSSL-fips-1_2-stable
    • refs/heads/OpenSSL-fips-2_0-dev
    • refs/heads/OpenSSL-fips-2_0-stable
    • refs/heads/OpenSSL-fips2-0_9_7-stable
    • refs/heads/OpenSSL_0_9_6-stable
    • refs/heads/OpenSSL_0_9_7-stable
    • refs/heads/OpenSSL_0_9_8-stable
    • refs/heads/OpenSSL_0_9_8fg-stable
    • refs/heads/OpenSSL_1_0_0-stable
    • refs/heads/OpenSSL_1_0_1-stable
    • refs/heads/OpenSSL_1_0_2-stable
    • refs/heads/OpenSSL_1_1_0-stable
    • refs/heads/OpenSSL_1_1_1-stable
    • refs/heads/SSLeay
    • refs/heads/feature/dtls-1.3
    • refs/heads/feature/ech
    • refs/heads/feature/quic-server
    • refs/heads/master
    • refs/heads/openssl-3.0
    • refs/heads/openssl-3.1
    • refs/heads/openssl-3.2
    • refs/heads/openssl-3.3
    • refs/heads/openssl-3.4
    • refs/heads/tls1.3-draft-18
    • refs/heads/tls1.3-draft-19
    • refs/tags/AFTER_COMPAQ_PATCH
    • refs/tags/BEFORE_COMPAQ_PATCH
    • refs/tags/BEFORE_engine
    • refs/tags/BEN_FIPS_TEST_1
    • refs/tags/BEN_FIPS_TEST_2
    • refs/tags/BEN_FIPS_TEST_3
    • refs/tags/BEN_FIPS_TEST_4
    • refs/tags/BEN_FIPS_TEST_5
    • refs/tags/BEN_FIPS_TEST_6
    • refs/tags/BEN_FIPS_TEST_7
    • refs/tags/BEN_FIPS_TEST_8
    • refs/tags/FIPS_098_TEST_1
    • refs/tags/FIPS_098_TEST_2
    • refs/tags/FIPS_098_TEST_3
    • refs/tags/FIPS_098_TEST_4
    • refs/tags/FIPS_098_TEST_5
    • refs/tags/FIPS_098_TEST_6
    • refs/tags/FIPS_098_TEST_7
    • refs/tags/FIPS_098_TEST_8
    • refs/tags/FIPS_TEST_10
    • refs/tags/FIPS_TEST_9
    • refs/tags/LEVITTE_after_const
    • refs/tags/LEVITTE_before_const
    • refs/tags/OpenSSL-engine-0_9_6
    • refs/tags/OpenSSL-engine-0_9_6-beta1
    • refs/tags/OpenSSL-engine-0_9_6-beta2
    • refs/tags/OpenSSL-engine-0_9_6-beta3
    • refs/tags/OpenSSL-engine-0_9_6a
    • refs/tags/OpenSSL-engine-0_9_6a-beta1
    • refs/tags/OpenSSL-engine-0_9_6a-beta2
    • refs/tags/OpenSSL-engine-0_9_6a-beta3
    • refs/tags/OpenSSL-engine-0_9_6b
    • refs/tags/OpenSSL-engine-0_9_6c
    • refs/tags/OpenSSL-engine-0_9_6d
    • refs/tags/OpenSSL-engine-0_9_6d-beta1
    • refs/tags/OpenSSL-engine-0_9_6e
    • refs/tags/OpenSSL-engine-0_9_6f
    • refs/tags/OpenSSL-engine-0_9_6g
    • refs/tags/OpenSSL-engine-0_9_6h
    • refs/tags/OpenSSL-engine-0_9_6i
    • refs/tags/OpenSSL-engine-0_9_6j
    • refs/tags/OpenSSL-engine-0_9_6k
    • refs/tags/OpenSSL-engine-0_9_6l
    • refs/tags/OpenSSL-engine-0_9_6m
    • refs/tags/OpenSSL-fips-1_2_0
    • refs/tags/OpenSSL-fips-1_2_1
    • refs/tags/OpenSSL-fips-1_2_2
    • refs/tags/OpenSSL-fips-1_2_3
    • refs/tags/OpenSSL-fips-2_0
    • refs/tags/OpenSSL-fips-2_0-pl1
    • refs/tags/OpenSSL-fips-2_0-rc1
    • refs/tags/OpenSSL-fips-2_0-rc2
    • refs/tags/OpenSSL-fips-2_0-rc3
    • refs/tags/OpenSSL-fips-2_0-rc4
    • refs/tags/OpenSSL-fips-2_0-rc5
    • refs/tags/OpenSSL-fips-2_0-rc6
    • refs/tags/OpenSSL-fips-2_0-rc7
    • refs/tags/OpenSSL-fips-2_0-rc8
    • refs/tags/OpenSSL-fips-2_0-rc9
    • refs/tags/OpenSSL-fips-2_0_1
    • refs/tags/OpenSSL_0_9_1c
    • refs/tags/OpenSSL_0_9_2b
    • refs/tags/OpenSSL_0_9_3
    • refs/tags/OpenSSL_0_9_3a
    • refs/tags/OpenSSL_0_9_3beta1
    • refs/tags/OpenSSL_0_9_3beta2
    • refs/tags/OpenSSL_0_9_4
    • refs/tags/OpenSSL_0_9_5
    • refs/tags/OpenSSL_0_9_5a
    • refs/tags/OpenSSL_0_9_5a-beta1
    • refs/tags/OpenSSL_0_9_5a-beta2
    • refs/tags/OpenSSL_0_9_5beta1
    • refs/tags/OpenSSL_0_9_5beta2
    • refs/tags/OpenSSL_0_9_6
    • refs/tags/OpenSSL_0_9_6-beta1
    • refs/tags/OpenSSL_0_9_6-beta2
    • refs/tags/OpenSSL_0_9_6-beta3
    • refs/tags/OpenSSL_0_9_6a
    • refs/tags/OpenSSL_0_9_6a-beta1
    • refs/tags/OpenSSL_0_9_6a-beta2
    • refs/tags/OpenSSL_0_9_6a-beta3
    • refs/tags/OpenSSL_0_9_6b
    • refs/tags/OpenSSL_0_9_6c
    • refs/tags/OpenSSL_0_9_6d
    • refs/tags/OpenSSL_0_9_6d-beta1
    • refs/tags/OpenSSL_0_9_6e
    • refs/tags/OpenSSL_0_9_6f
    • refs/tags/OpenSSL_0_9_6g
    • refs/tags/OpenSSL_0_9_6h
    • refs/tags/OpenSSL_0_9_6i
    • refs/tags/OpenSSL_0_9_6j
    • refs/tags/OpenSSL_0_9_6k
    • refs/tags/OpenSSL_0_9_6l
    • refs/tags/OpenSSL_0_9_6m
    • refs/tags/OpenSSL_0_9_7
    • refs/tags/OpenSSL_0_9_7-beta1
    • refs/tags/OpenSSL_0_9_7-beta2
    • refs/tags/OpenSSL_0_9_7-beta3
    • refs/tags/OpenSSL_0_9_7-beta4
    • refs/tags/OpenSSL_0_9_7-beta5
    • refs/tags/OpenSSL_0_9_7-beta6
    • refs/tags/OpenSSL_0_9_7a
    • refs/tags/OpenSSL_0_9_7b
    • refs/tags/OpenSSL_0_9_7c
    • refs/tags/OpenSSL_0_9_7d
    • refs/tags/OpenSSL_0_9_7e
    • refs/tags/OpenSSL_0_9_7f
    • refs/tags/OpenSSL_0_9_7g
    • refs/tags/OpenSSL_0_9_7h
    • refs/tags/OpenSSL_0_9_7i
    • refs/tags/OpenSSL_0_9_7j
    • refs/tags/OpenSSL_0_9_7k
    • refs/tags/OpenSSL_0_9_7l
    • refs/tags/OpenSSL_0_9_7m
    • refs/tags/OpenSSL_0_9_8
    • refs/tags/OpenSSL_0_9_8-beta1
    • refs/tags/OpenSSL_0_9_8-beta2
    • refs/tags/OpenSSL_0_9_8-beta3
    • refs/tags/OpenSSL_0_9_8-beta4
    • refs/tags/OpenSSL_0_9_8-beta5
    • refs/tags/OpenSSL_0_9_8-beta6
    • refs/tags/OpenSSL_0_9_8a
    • refs/tags/OpenSSL_0_9_8b
    • refs/tags/OpenSSL_0_9_8c
    • refs/tags/OpenSSL_0_9_8d
    • refs/tags/OpenSSL_0_9_8e
    • refs/tags/OpenSSL_0_9_8f
    • refs/tags/OpenSSL_0_9_8g
    • refs/tags/OpenSSL_0_9_8h
    • refs/tags/OpenSSL_0_9_8i
    • refs/tags/OpenSSL_0_9_8j
    • refs/tags/OpenSSL_0_9_8k
    • refs/tags/OpenSSL_0_9_8l
    • refs/tags/OpenSSL_0_9_8m
    • refs/tags/OpenSSL_0_9_8m-beta1
    • refs/tags/OpenSSL_0_9_8n
    • refs/tags/OpenSSL_0_9_8o
    • refs/tags/OpenSSL_0_9_8p
    • refs/tags/OpenSSL_0_9_8q
    • refs/tags/OpenSSL_0_9_8r
    • refs/tags/OpenSSL_0_9_8s
    • refs/tags/OpenSSL_0_9_8t
    • refs/tags/OpenSSL_0_9_8u
    • refs/tags/OpenSSL_0_9_8v
    • refs/tags/OpenSSL_0_9_8w
    • refs/tags/OpenSSL_0_9_8x
    • refs/tags/OpenSSL_1_0_0
    • refs/tags/OpenSSL_1_0_0-beta1
    • refs/tags/OpenSSL_1_0_0-beta2
    • refs/tags/OpenSSL_1_0_0-beta3
    • refs/tags/OpenSSL_1_0_0-beta4
    • refs/tags/OpenSSL_1_0_0-beta5
    • refs/tags/OpenSSL_1_0_0a
    • refs/tags/OpenSSL_1_0_0b
    • refs/tags/OpenSSL_1_0_0c
    • refs/tags/OpenSSL_1_0_0d
    • refs/tags/OpenSSL_1_0_0e
    • refs/tags/OpenSSL_1_0_0f
    • refs/tags/OpenSSL_1_0_0g
    • refs/tags/OpenSSL_1_0_0h
    • refs/tags/OpenSSL_1_0_0i
    • refs/tags/OpenSSL_1_0_0j
    • refs/tags/OpenSSL_1_0_1
    • refs/tags/OpenSSL_1_0_1-beta1
    • refs/tags/OpenSSL_1_0_1-beta2
    • refs/tags/OpenSSL_1_0_1-beta3
    • refs/tags/OpenSSL_1_0_1a
    • refs/tags/OpenSSL_1_0_1b
    • refs/tags/OpenSSL_1_0_1c
    • refs/tags/OpenSSL_FIPS_1_0
    • refs/tags/SSLeay_0_8_1b
    • refs/tags/SSLeay_0_9_0b
    • refs/tags/SSLeay_0_9_1b
    • refs/tags/STATE_after_zlib
    • refs/tags/STATE_before_zlib
    • refs/tags/rsaref
    • openssl-3.4.0-alpha1
    • openssl-3.3.2
    • openssl-3.3.1
    • openssl-3.3.0-beta1
    • openssl-3.3.0-alpha1
    • openssl-3.3.0
    • openssl-3.2.3
    • openssl-3.2.2
    • openssl-3.2.1
    • openssl-3.2.0-beta1
    • openssl-3.2.0-alpha2
    • openssl-3.2.0-alpha1
    • openssl-3.2.0
    • openssl-3.1.7
    • openssl-3.1.6
    • openssl-3.1.5
    • openssl-3.1.4
    • openssl-3.1.3
    • openssl-3.1.2
    • openssl-3.1.1
    • openssl-3.1.0-beta1
    • openssl-3.1.0-alpha1
    • openssl-3.1.0
    • openssl-3.0.9
    • openssl-3.0.8
    • openssl-3.0.7
    • openssl-3.0.6
    • openssl-3.0.5
    • openssl-3.0.4
    • openssl-3.0.3
    • openssl-3.0.2
    • openssl-3.0.15
    • openssl-3.0.14
    • openssl-3.0.13
    • openssl-3.0.12
    • openssl-3.0.11
    • openssl-3.0.10
    • openssl-3.0.1
    • openssl-3.0.0-beta2
    • openssl-3.0.0-beta1
    • openssl-3.0.0-alpha9
    • openssl-3.0.0-alpha8
    • openssl-3.0.0-alpha7
    • openssl-3.0.0-alpha6
    • openssl-3.0.0-alpha5
    • openssl-3.0.0-alpha4
    • openssl-3.0.0-alpha3
    • openssl-3.0.0-alpha2
    • openssl-3.0.0-alpha17
    • openssl-3.0.0-alpha16
    • openssl-3.0.0-alpha15
    • openssl-3.0.0-alpha14
    • openssl-3.0.0-alpha13
    • openssl-3.0.0-alpha12
    • openssl-3.0.0-alpha11
    • openssl-3.0.0-alpha10
    • openssl-3.0.0-alpha1
    • openssl-3.0.0
    • master-pre-reformat
    • master-pre-auto-reformat
    • master-post-reformat
    • master-post-auto-reformat
    • OpenSSL_1_1_1w
    • OpenSSL_1_1_1v
    • OpenSSL_1_1_1u
    • OpenSSL_1_1_1t
    • OpenSSL_1_1_1s
    • OpenSSL_1_1_1r
    • OpenSSL_1_1_1q
    • OpenSSL_1_1_1p
    • OpenSSL_1_1_1o
    • OpenSSL_1_1_1n
    • OpenSSL_1_1_1m
    • OpenSSL_1_1_1l
    • OpenSSL_1_1_1k
    • OpenSSL_1_1_1j
    • OpenSSL_1_1_1i
    • OpenSSL_1_1_1h
    • OpenSSL_1_1_1g
    • OpenSSL_1_1_1f
    • OpenSSL_1_1_1e
    • OpenSSL_1_1_1d
    • OpenSSL_1_1_1c
    • OpenSSL_1_1_1b
    • OpenSSL_1_1_1a
    • OpenSSL_1_1_1-pre9
    • OpenSSL_1_1_1-pre8
    • OpenSSL_1_1_1-pre7
    • OpenSSL_1_1_1-pre6
    • OpenSSL_1_1_1-pre5
    • OpenSSL_1_1_1-pre4
    • OpenSSL_1_1_1-pre3
    • OpenSSL_1_1_1-pre2
    • OpenSSL_1_1_1-pre1
    • OpenSSL_1_1_1
    • OpenSSL_1_1_0l
    • OpenSSL_1_1_0k
    • OpenSSL_1_1_0j
    • OpenSSL_1_1_0i
    • OpenSSL_1_1_0h
    • OpenSSL_1_1_0g
    • OpenSSL_1_1_0f
    • OpenSSL_1_1_0e
    • OpenSSL_1_1_0d
    • OpenSSL_1_1_0c
    • OpenSSL_1_1_0b
    • OpenSSL_1_1_0a
    • OpenSSL_1_1_0-pre6
    • OpenSSL_1_1_0-pre5
    • OpenSSL_1_1_0-pre4
    • OpenSSL_1_1_0-pre3
    • OpenSSL_1_1_0-pre2
    • OpenSSL_1_1_0-pre1
    • OpenSSL_1_1_0
    • OpenSSL_1_0_2u
    • OpenSSL_1_0_2t
    • OpenSSL_1_0_2s
    • OpenSSL_1_0_2r
    • OpenSSL_1_0_2q
    • OpenSSL_1_0_2p
    • OpenSSL_1_0_2o
    • OpenSSL_1_0_2n
    • OpenSSL_1_0_2m
    • OpenSSL_1_0_2l
    • OpenSSL_1_0_2k
    • OpenSSL_1_0_2j
    • OpenSSL_1_0_2i
    • OpenSSL_1_0_2h
    • OpenSSL_1_0_2g
    • OpenSSL_1_0_2f
    • OpenSSL_1_0_2e
    • OpenSSL_1_0_2d
    • OpenSSL_1_0_2c
    • OpenSSL_1_0_2b
    • OpenSSL_1_0_2a
    • OpenSSL_1_0_2-pre-reformat
    • OpenSSL_1_0_2-pre-auto-reformat
    • OpenSSL_1_0_2-post-reformat
    • OpenSSL_1_0_2-post-auto-reformat
    • OpenSSL_1_0_2-beta3
    • OpenSSL_1_0_2-beta2
    • OpenSSL_1_0_2-beta1
    • OpenSSL_1_0_2
    • OpenSSL_1_0_1u
    • OpenSSL_1_0_1t
    • OpenSSL_1_0_1s
    • OpenSSL_1_0_1r
    • OpenSSL_1_0_1q
    • OpenSSL_1_0_1p
    • OpenSSL_1_0_1o
    • OpenSSL_1_0_1n
    • OpenSSL_1_0_1m
    • OpenSSL_1_0_1l
    • OpenSSL_1_0_1k
    • OpenSSL_1_0_1j
    • OpenSSL_1_0_1i
    • OpenSSL_1_0_1h
    • OpenSSL_1_0_1g
    • OpenSSL_1_0_1f
    • OpenSSL_1_0_1e
    • OpenSSL_1_0_1d
    • OpenSSL_1_0_1-pre-reformat
    • OpenSSL_1_0_1-pre-auto-reformat
    • OpenSSL_1_0_1-post-reformat
    • OpenSSL_1_0_1-post-auto-reformat
    • OpenSSL_1_0_0t
    • OpenSSL_1_0_0s
    • OpenSSL_1_0_0r
    • OpenSSL_1_0_0q
    • OpenSSL_1_0_0p
    • OpenSSL_1_0_0o
    • OpenSSL_1_0_0n
    • OpenSSL_1_0_0m
    • OpenSSL_1_0_0l
    • OpenSSL_1_0_0k
    • OpenSSL_1_0_0-pre-reformat
    • OpenSSL_1_0_0-pre-auto-reformat
    • OpenSSL_1_0_0-post-reformat
    • OpenSSL_1_0_0-post-auto-reformat
    • OpenSSL_0_9_8zh
    • OpenSSL_0_9_8zg
    • OpenSSL_0_9_8zf
    • OpenSSL_0_9_8ze
    • OpenSSL_0_9_8zd
    • OpenSSL_0_9_8zc
    • OpenSSL_0_9_8zb
    • OpenSSL_0_9_8za
    • OpenSSL_0_9_8y
    • OpenSSL_0_9_8-pre-reformat
    • OpenSSL_0_9_8-pre-auto-reformat
    • OpenSSL_0_9_8-post-reformat
    • OpenSSL_0_9_8-post-auto-reformat
    • OpenSSL-fips-2_0_9
    • OpenSSL-fips-2_0_8
    • OpenSSL-fips-2_0_7
    • OpenSSL-fips-2_0_6
    • OpenSSL-fips-2_0_5
    • OpenSSL-fips-2_0_4
    • OpenSSL-fips-2_0_3
    • OpenSSL-fips-2_0_2
    • OpenSSL-fips-2_0_16
    • OpenSSL-fips-2_0_15
    • OpenSSL-fips-2_0_14
    • OpenSSL-fips-2_0_13
    • OpenSSL-fips-2_0_12
    • OpenSSL-fips-2_0_11
    • OpenSSL-fips-2_0_10
  • 8af65a6
  • /
  • crypto
  • /
  • rand
  • /
  • drbg_ctr.c
Raw File
Permalinks

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • content
  • directory
  • revision
  • snapshot
  • release
content badge Iframe embedding
swh:1:cnt:fe15164451e8ec1df98f7102a549c4ce4562722c
directory badge Iframe embedding
swh:1:dir:640cbd436ac18287d01dc87c395d92e9879d12f2
revision badge
swh:1:rev:4ff3df161c8b0caf0acac2e0a19980ccd4173a66
snapshot badge
swh:1:snp:dc2a5002442a00b1c0eda7c65d04ea7455e166cd
release badge
swh:1:rel:1a7c70caec83e52b03df96e83d937eb39ae7424d
Tip revision: 4ff3df161c8b0caf0acac2e0a19980ccd4173a66 authored by Richard Levitte on 17 April 2018, 13:32:02 UTC
Prepare for 1.1.1-pre5 release
Tip revision: 4ff3df1
drbg_ctr.c
/*
 * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <stdlib.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include "internal/thread_once.h"
#include "internal/thread_once.h"
#include "rand_lcl.h"
/*
 * Implementation of NIST SP 800-90A CTR DRBG.
 */

static void inc_128(RAND_DRBG_CTR *ctr)
{
    int i;
    unsigned char c;
    unsigned char *p = &ctr->V[15];

    for (i = 0; i < 16; i++, p--) {
        c = *p;
        c++;
        *p = c;
        if (c != 0) {
            /* If we didn't wrap around, we're done. */
            break;
        }
    }
}

static void ctr_XOR(RAND_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
{
    size_t i, n;

    if (in == NULL || inlen == 0)
        return;

    /*
     * Any zero padding will have no effect on the result as we
     * are XORing. So just process however much input we have.
     */
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
    for (i = 0; i < n; i++)
        ctr->K[i] ^= in[i];
    if (inlen <= ctr->keylen)
        return;

    n = inlen - ctr->keylen;
    if (n > 16) {
        /* Should never happen */
        n = 16;
    }
    for (i = 0; i < n; i++)
        ctr->V[i] ^= in[i + ctr->keylen];
}

/*
 * Process a complete block using BCC algorithm of SP 800-90A 10.3.3
 */
__owur static int ctr_BCC_block(RAND_DRBG_CTR *ctr, unsigned char *out,
                                const unsigned char *in)
{
    int i, outlen = AES_BLOCK_SIZE;

    for (i = 0; i < 16; i++)
        out[i] ^= in[i];

    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, AES_BLOCK_SIZE)
        || outlen != AES_BLOCK_SIZE)
        return 0;
    return 1;
}


/*
 * Handle several BCC operations for as much data as we need for K and X
 */
__owur static int ctr_BCC_blocks(RAND_DRBG_CTR *ctr, const unsigned char *in)
{
    if (!ctr_BCC_block(ctr, ctr->KX, in)
        || !ctr_BCC_block(ctr, ctr->KX + 16, in))
        return 0;
    if (ctr->keylen != 16 && !ctr_BCC_block(ctr, ctr->KX + 32, in))
        return 0;
    return 1;
}

/*
 * Initialise BCC blocks: these have the value 0,1,2 in leftmost positions:
 * see 10.3.1 stage 7.
 */
__owur static int ctr_BCC_init(RAND_DRBG_CTR *ctr)
{
    memset(ctr->KX, 0, 48);
    memset(ctr->bltmp, 0, 16);
    if (!ctr_BCC_block(ctr, ctr->KX, ctr->bltmp))
        return 0;
    ctr->bltmp[3] = 1;
    if (!ctr_BCC_block(ctr, ctr->KX + 16, ctr->bltmp))
        return 0;
    if (ctr->keylen != 16) {
        ctr->bltmp[3] = 2;
        if (!ctr_BCC_block(ctr, ctr->KX + 32, ctr->bltmp))
            return 0;
    }
    return 1;
}

/*
 * Process several blocks into BCC algorithm, some possibly partial
 */
__owur static int ctr_BCC_update(RAND_DRBG_CTR *ctr,
                                 const unsigned char *in, size_t inlen)
{
    if (in == NULL || inlen == 0)
        return 1;

    /* If we have partial block handle it first */
    if (ctr->bltmp_pos) {
        size_t left = 16 - ctr->bltmp_pos;

        /* If we now have a complete block process it */
        if (inlen >= left) {
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
                return 0;
            ctr->bltmp_pos = 0;
            inlen -= left;
            in += left;
        }
    }

    /* Process zero or more complete blocks */
    for (; inlen >= 16; in += 16, inlen -= 16) {
        if (!ctr_BCC_blocks(ctr, in))
            return 0;
    }

    /* Copy any remaining partial block to the temporary buffer */
    if (inlen > 0) {
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
        ctr->bltmp_pos += inlen;
    }
    return 1;
}

__owur static int ctr_BCC_final(RAND_DRBG_CTR *ctr)
{
    if (ctr->bltmp_pos) {
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
            return 0;
    }
    return 1;
}

__owur static int ctr_df(RAND_DRBG_CTR *ctr,
                         const unsigned char *in1, size_t in1len,
                         const unsigned char *in2, size_t in2len,
                         const unsigned char *in3, size_t in3len)
{
    static unsigned char c80 = 0x80;
    size_t inlen;
    unsigned char *p = ctr->bltmp;
    int outlen = AES_BLOCK_SIZE;

    if (!ctr_BCC_init(ctr))
        return 0;
    if (in1 == NULL)
        in1len = 0;
    if (in2 == NULL)
        in2len = 0;
    if (in3 == NULL)
        in3len = 0;
    inlen = in1len + in2len + in3len;
    /* Initialise L||N in temporary block */
    *p++ = (inlen >> 24) & 0xff;
    *p++ = (inlen >> 16) & 0xff;
    *p++ = (inlen >> 8) & 0xff;
    *p++ = inlen & 0xff;

    /* NB keylen is at most 32 bytes */
    *p++ = 0;
    *p++ = 0;
    *p++ = 0;
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
    ctr->bltmp_pos = 8;
    if (!ctr_BCC_update(ctr, in1, in1len)
        || !ctr_BCC_update(ctr, in2, in2len)
        || !ctr_BCC_update(ctr, in3, in3len)
        || !ctr_BCC_update(ctr, &c80, 1)
        || !ctr_BCC_final(ctr))
        return 0;
    /* Set up key K */
    if (!EVP_CipherInit_ex(ctr->ctx, ctr->cipher, NULL, ctr->KX, NULL, 1))
        return 0;
    /* X follows key K */
    if (!EVP_CipherUpdate(ctr->ctx, ctr->KX, &outlen, ctr->KX + ctr->keylen,
                          AES_BLOCK_SIZE)
        || outlen != AES_BLOCK_SIZE)
        return 0;
    if (!EVP_CipherUpdate(ctr->ctx, ctr->KX + 16, &outlen, ctr->KX,
                          AES_BLOCK_SIZE)
        || outlen != AES_BLOCK_SIZE)
        return 0;
    if (ctr->keylen != 16)
        if (!EVP_CipherUpdate(ctr->ctx, ctr->KX + 32, &outlen, ctr->KX + 16,
                              AES_BLOCK_SIZE)
            || outlen != AES_BLOCK_SIZE)
            return 0;
    return 1;
}

/*
 * NB the no-df Update in SP800-90A specifies a constant input length
 * of seedlen, however other uses of this algorithm pad the input with
 * zeroes if necessary and have up to two parameters XORed together,
 * so we handle both cases in this function instead.
 */
__owur static int ctr_update(RAND_DRBG *drbg,
                             const unsigned char *in1, size_t in1len,
                             const unsigned char *in2, size_t in2len,
                             const unsigned char *nonce, size_t noncelen)
{
    RAND_DRBG_CTR *ctr = &drbg->data.ctr;
    int outlen = AES_BLOCK_SIZE;

    /* correct key is already set up. */
    inc_128(ctr);
    if (!EVP_CipherUpdate(ctr->ctx, ctr->K, &outlen, ctr->V, AES_BLOCK_SIZE)
        || outlen != AES_BLOCK_SIZE)
        return 0;

    /* If keylen longer than 128 bits need extra encrypt */
    if (ctr->keylen != 16) {
        inc_128(ctr);
        if (!EVP_CipherUpdate(ctr->ctx, ctr->K+16, &outlen, ctr->V,
                              AES_BLOCK_SIZE)
            || outlen != AES_BLOCK_SIZE)
            return 0;
    }
    inc_128(ctr);
    if (!EVP_CipherUpdate(ctr->ctx, ctr->V, &outlen, ctr->V, AES_BLOCK_SIZE)
        || outlen != AES_BLOCK_SIZE)
        return 0;

    /* If 192 bit key part of V is on end of K */
    if (ctr->keylen == 24) {
        memcpy(ctr->V + 8, ctr->V, 8);
        memcpy(ctr->V, ctr->K + 24, 8);
    }

    if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) {
        /* If no input reuse existing derived value */
        if (in1 != NULL || nonce != NULL || in2 != NULL)
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
                return 0;
        /* If this a reuse input in1len != 0 */
        if (in1len)
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
    } else {
        ctr_XOR(ctr, in1, in1len);
        ctr_XOR(ctr, in2, in2len);
    }

    if (!EVP_CipherInit_ex(ctr->ctx, ctr->cipher, NULL, ctr->K, NULL, 1))
        return 0;
    return 1;
}

__owur static int drbg_ctr_instantiate(RAND_DRBG *drbg,
                                       const unsigned char *entropy, size_t entropylen,
                                       const unsigned char *nonce, size_t noncelen,
                                       const unsigned char *pers, size_t perslen)
{
    RAND_DRBG_CTR *ctr = &drbg->data.ctr;

    if (entropy == NULL)
        return 0;

    memset(ctr->K, 0, sizeof(ctr->K));
    memset(ctr->V, 0, sizeof(ctr->V));
    if (!EVP_CipherInit_ex(ctr->ctx, ctr->cipher, NULL, ctr->K, NULL, 1))
        return 0;
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
        return 0;
    return 1;
}

__owur static int drbg_ctr_reseed(RAND_DRBG *drbg,
                                  const unsigned char *entropy, size_t entropylen,
                                  const unsigned char *adin, size_t adinlen)
{
    if (entropy == NULL)
        return 0;
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
        return 0;
    return 1;
}

__owur static int drbg_ctr_generate(RAND_DRBG *drbg,
                                    unsigned char *out, size_t outlen,
                                    const unsigned char *adin, size_t adinlen)
{
    RAND_DRBG_CTR *ctr = &drbg->data.ctr;

    if (adin != NULL && adinlen != 0) {
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
            return 0;
        /* This means we reuse derived value */
        if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) {
            adin = NULL;
            adinlen = 1;
        }
    } else {
        adinlen = 0;
    }

    for ( ; ; ) {
        int outl = AES_BLOCK_SIZE;

        inc_128(ctr);
        if (outlen < 16) {
            /* Use K as temp space as it will be updated */
            if (!EVP_CipherUpdate(ctr->ctx, ctr->K, &outl, ctr->V,
                                  AES_BLOCK_SIZE)
                || outl != AES_BLOCK_SIZE)
                return 0;
            memcpy(out, ctr->K, outlen);
            break;
        }
        if (!EVP_CipherUpdate(ctr->ctx, out, &outl, ctr->V, AES_BLOCK_SIZE)
            || outl != AES_BLOCK_SIZE)
            return 0;
        out += 16;
        outlen -= 16;
        if (outlen == 0)
            break;
    }

    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
        return 0;
    return 1;
}

static int drbg_ctr_uninstantiate(RAND_DRBG *drbg)
{
    EVP_CIPHER_CTX_free(drbg->data.ctr.ctx);
    EVP_CIPHER_CTX_free(drbg->data.ctr.ctx_df);
    OPENSSL_cleanse(&drbg->data.ctr, sizeof(drbg->data.ctr));
    return 1;
}

static RAND_DRBG_METHOD drbg_ctr_meth = {
    drbg_ctr_instantiate,
    drbg_ctr_reseed,
    drbg_ctr_generate,
    drbg_ctr_uninstantiate
};

int drbg_ctr_init(RAND_DRBG *drbg)
{
    RAND_DRBG_CTR *ctr = &drbg->data.ctr;
    size_t keylen;

    switch (drbg->type) {
    default:
        /* This can't happen, but silence the compiler warning. */
        return 0;
    case NID_aes_128_ctr:
        keylen = 16;
        ctr->cipher = EVP_aes_128_ecb();
        break;
    case NID_aes_192_ctr:
        keylen = 24;
        ctr->cipher = EVP_aes_192_ecb();
        break;
    case NID_aes_256_ctr:
        keylen = 32;
        ctr->cipher = EVP_aes_256_ecb();
        break;
    }

    drbg->meth = &drbg_ctr_meth;

    ctr->keylen = keylen;
    if (ctr->ctx == NULL)
        ctr->ctx = EVP_CIPHER_CTX_new();
    if (ctr->ctx == NULL)
        return 0;
    drbg->strength = keylen * 8;
    drbg->seedlen = keylen + 16;

    if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) {
        /* df initialisation */
        static const unsigned char df_key[32] = {
            0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
            0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
            0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
            0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
        };

        if (ctr->ctx_df == NULL)
            ctr->ctx_df = EVP_CIPHER_CTX_new();
        if (ctr->ctx_df == NULL)
            return 0;
        /* Set key schedule for df_key */
        if (!EVP_CipherInit_ex(ctr->ctx_df, ctr->cipher, NULL, df_key, NULL, 1))
            return 0;

        drbg->min_entropylen = ctr->keylen;
        drbg->max_entropylen = DRBG_MINMAX_FACTOR * drbg->min_entropylen;
        drbg->min_noncelen = drbg->min_entropylen / 2;
        drbg->max_noncelen = DRBG_MINMAX_FACTOR * drbg->min_noncelen;
        drbg->max_perslen = DRBG_MAX_LENGTH;
        drbg->max_adinlen = DRBG_MAX_LENGTH;
    } else {
        drbg->min_entropylen = drbg->seedlen;
        drbg->max_entropylen = drbg->seedlen;
        /* Nonce not used */
        drbg->min_noncelen = 0;
        drbg->max_noncelen = 0;
        drbg->max_perslen = drbg->seedlen;
        drbg->max_adinlen = drbg->seedlen;
    }

    drbg->max_request = 1 << 16;

    return 1;
}

ENEA — Copyright (C), ENEA. License: GNU AGPLv3+.
Legal notes  ::  JavaScript license information ::  Web API

back to top