コード例 #1
0
ファイル: s2n_rsa.c プロジェクト: Gorelli/s2n
int s2n_rsa_keys_match(struct s2n_rsa_public_key *pub, struct s2n_rsa_private_key *priv)
{
    uint8_t plain_inpad[36], plain_outpad[36], encpad[8192];
    struct s2n_blob plain_in, plain_out, enc;

    plain_in.data = plain_inpad;
    plain_in.size = sizeof(plain_inpad);
    GUARD(s2n_get_private_random_data(&plain_in));

    enc.data = encpad;
    enc.size = s2n_rsa_public_encrypted_size(pub);
    lte_check(enc.size, sizeof(encpad));
    GUARD(s2n_rsa_encrypt(pub, &plain_in, &enc));

    plain_out.data = plain_outpad;
    plain_out.size = sizeof(plain_outpad);
    GUARD(s2n_rsa_decrypt(priv, &enc, &plain_out));

    if (memcmp(plain_in.data, plain_out.data, plain_in.size)) {
        S2N_ERROR(S2N_ERR_KEY_MISMATCH);
    }

    return 0;
}
コード例 #2
0
ファイル: s2n_random.c プロジェクト: baldwinmatt/s2n
int64_t s2n_public_random(int64_t max)
{
    uint64_t r;

    gt_check(max, 0);

    while(1) {
        struct s2n_blob blob = { .data = (void *) &r, sizeof(r) };
        GUARD(s2n_get_public_random_data(&blob));

        /* Imagine an int was one byte and UINT_MAX was 256. If the
         * caller asked for s2n_random(129, ...) we'd end up in
         * trouble. Each number in the range 0...127 would be twice
         * as likely as 128. That's because r == 0 % 129 -> 0, and
         * r == 129 % 129 -> 0, but only r == 128 returns 128,
         * r == 257 is out of range.
         *
         * To de-bias the dice, we discard values of r that are higher
         * that the highest multiple of 'max' an int can support. If
         * max is a uint, then in the worst case we discard 50% - 1 r's.
         * But since 'max' is an int and INT_MAX is <= UINT_MAX / 2,
         * in the worst case we discard 25% - 1 r's.
         */
        if (r < (UINT64_MAX - (UINT64_MAX % max))) {
            return r % max;
        }
    }

    return -1;
}

#ifndef OPENSSL_IS_BORINGSSL

int s2n_openssl_compat_rand(unsigned char *buf, int num)
{
    struct s2n_blob out = {.data = buf, .size = num};

    if(s2n_get_private_random_data(&out) < 0) {
        return 0;
    }
    return 1;
}

int s2n_openssl_compat_status(void)
{
    return 1;
}

int s2n_openssl_compat_init(ENGINE *unused)
{
    return 1;
}

RAND_METHOD s2n_openssl_rand_method = {
    .seed = NULL,
    .bytes = s2n_openssl_compat_rand,
    .cleanup = NULL,
    .add = NULL,
    .pseudorand = s2n_openssl_compat_rand,
    .status = s2n_openssl_compat_status
};
#endif

int s2n_init(void)
{
    GUARD(s2n_mem_init());

    OPEN:
    entropy_fd = open(ENTROPY_SOURCE, O_RDONLY);
    if (entropy_fd == -1) {
        if (errno == EINTR) {
            goto OPEN;
        }
        S2N_ERROR(S2N_ERR_OPEN_RANDOM);
    }

#if defined(MAP_INHERIT_ZERO)
    if ((zero_if_forked_ptr = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE,
                                   MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
        S2N_ERROR(S2N_ERR_OPEN_RANDOM);
    }

    if (minherit(zero_if_forked_ptr, sizeof(int), MAP_INHERIT_ZERO) == -1) {
        S2N_ERROR(S2N_ERR_OPEN_RANDOM);
    }
#else

    if (pthread_atfork(NULL, NULL, s2n_on_fork) != 0) {
        S2N_ERROR(S2N_ERR_OPEN_RANDOM);
    }
#endif

    GUARD(s2n_check_fork());

#ifndef OPENSSL_IS_BORINGSSL
    /* Create an engine */
    ENGINE *e = ENGINE_new();
    if (e == NULL ||
        ENGINE_set_id(e, "s2n") != 1 ||
        ENGINE_set_name(e, "s2n entropy generator") != 1 ||
        ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) != 1 ||
        ENGINE_set_init_function(e, s2n_openssl_compat_init) != 1 ||
        ENGINE_set_RAND(e, &s2n_openssl_rand_method) != 1 ||
        ENGINE_add(e) != 1 ||
        ENGINE_free(e) != 1) {
        S2N_ERROR(S2N_ERR_OPEN_RANDOM);
    }

    /* Use that engine for rand() */
    e = ENGINE_by_id("s2n");
    if (e == NULL ||
        ENGINE_init(e) != 1 ||
        ENGINE_set_default(e, ENGINE_METHOD_RAND) != 1) {
        S2N_ERROR(S2N_ERR_OPEN_RANDOM);
    }

#endif

    return 0;
}
コード例 #3
0
ファイル: pq-random.c プロジェクト: alexw91/s2n
int get_random_bytes(OUT unsigned char *buffer, unsigned int num_bytes)
{
    struct s2n_blob out = {.data = buffer,.size = num_bytes };
    return s2n_get_private_random_data(&out);
}