Ejemplo n.º 1
0
int s2n_stuffer_write_hex(struct s2n_stuffer *stuffer, struct s2n_stuffer *in, uint32_t n)
{
    gte_check(s2n_stuffer_space_remaining(stuffer), n * 2);

    for (int i = 0; i < n; i++) {
        uint8_t c;
        GUARD(s2n_stuffer_read_uint8(in, &c));
        GUARD(s2n_stuffer_write_uint8_hex(stuffer, c));
    }

    return 0;
}
Ejemplo n.º 2
0
static int s2n_stuffer_pem_read_contents(struct s2n_stuffer *pem, struct s2n_stuffer *asn1)
{
    uint8_t base64_buf[64] = { 0 };
    struct s2n_blob base64__blob = { .data = base64_buf, .size = sizeof(base64_buf) };
    struct s2n_stuffer base64_stuffer = {{0}};
    GUARD(s2n_stuffer_init(&base64_stuffer, &base64__blob));

    while (1) {
        char c;
        /* Peek to see if the next char is a dash, meaning end of pem_contents */
        GUARD(s2n_stuffer_peek_char(pem, &c));
        if (c == '-') {
            break;
        } else {
            /* Else, move read pointer forward by 1 byte since we will be consuming it. */
             GUARD(s2n_stuffer_skip_read(pem, 1));
        }

         /* Skip non-base64 characters */
        if (!s2n_is_base64_char(c)) {
            continue;
        }

        /* Flush base64_stuffer to asn1 stuffer if we're out of space, and reset base64_stuffer read/write pointers */
        if (s2n_stuffer_space_remaining(&base64_stuffer) == 0) {
            GUARD(s2n_stuffer_read_base64(&base64_stuffer, asn1));
            GUARD(s2n_stuffer_rewrite(&base64_stuffer));
        }

        /* Copy next char to base64_stuffer */
        GUARD(s2n_stuffer_write_bytes(&base64_stuffer, (uint8_t *) &c, 1));

    };

    /* Flush any remaining bytes to asn1 */
    GUARD(s2n_stuffer_read_base64(&base64_stuffer, asn1));

    return 0;
}

static int s2n_stuffer_data_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1, const char *keyword)
{
    GUARD(s2n_stuffer_pem_read_begin(pem, keyword));
    GUARD(s2n_stuffer_pem_read_contents(pem, asn1));
    GUARD(s2n_stuffer_pem_read_end(pem, keyword));

    return 0;
}
Ejemplo n.º 3
0
/* Due to the need to support some older assemblers,
 * we cannot use either the compiler intrinsics or
 * the RDRAND assembly mnemonic. For this reason,
 * we're using the opcode directly (0F C7/6). This
 * stores the result in eax.
 *
 * volatile is important to prevent the compiler from
 * re-ordering or optimizing the use of RDRAND.
 */
int s2n_get_rdrand_data(struct s2n_blob *out)
{

#if defined(__x86_64__)||defined(__i386__)
    int space_remaining = 0;
    struct s2n_stuffer stuffer;
    union {
        uint64_t u64;
        uint8_t  u8[8];
    } output;

    GUARD(s2n_stuffer_init(&stuffer, out));

    while((space_remaining = s2n_stuffer_space_remaining(&stuffer))) {
        int success = 0;

        for (int tries = 0; tries < 10; tries++) {
            __asm__ __volatile__(
                ".byte 0x48;\n"
                ".byte 0x0f;\n"
                ".byte 0xc7;\n"
                ".byte 0xf0;\n"
                "adcl $0x00, %%ebx;\n"
                :"=b"(success), "=a"(output.u64)
                :"b"(0)
                :"cc"
            );

            if (success) {
                break;
            }
        }

        if (!success) {
            return -1;
        }

        int data_to_fill = MIN(sizeof(output), space_remaining);

        GUARD(s2n_stuffer_write_bytes(&stuffer, output.u8, data_to_fill));
    }

    return 0;
#else
    return -1;
#endif
}
Ejemplo n.º 4
0
int s2n_stuffer_skip_write(struct s2n_stuffer *stuffer, const uint32_t n)
{
    if (s2n_stuffer_space_remaining(stuffer) < n) {
        if (stuffer->growable) {
            /* Always grow a stuffer by at least 1k */
            uint32_t growth = n;
            if (growth < 1024) {
                growth = 1024;
            }
            GUARD(s2n_stuffer_resize(stuffer, stuffer->blob.size + growth));
        } else {
            S2N_ERROR(S2N_ERR_STUFFER_IS_FULL);
        }
    }

    stuffer->write_cursor += n;
    stuffer->wiped = 0;
    return 0;
}
Ejemplo n.º 5
0
/**
 * Helper function: read n bits of hex data.
 */
static int s2n_stuffer_read_n_bits_hex(struct s2n_stuffer *stuffer, uint8_t n, uint64_t *u)
{
    uint8_t hex_data[16];
    struct s2n_blob b = { .data = hex_data, .size = n / 4 };

    GUARD(s2n_stuffer_read(stuffer, &b));

    /* Start with u = 0 */
    *u = 0;

    for (int i = 0; i < b.size; i++) {
        *u <<= 4;
        if (b.data[i] >= '0' && b.data[i] <= '9') {
            *u |= b.data[i] - '0';
        } else if (b.data[i] >= 'a' && b.data[i] <= 'f') {
            *u |= b.data[i] - 'a' + 10;
        } else if (b.data[i] >= 'A' && b.data[i] <= 'F') {
            *u |= b.data[i] - 'A' + 10;
        } else {
            S2N_ERROR(S2N_ERR_BAD_MESSAGE);
        }
    }

    return 0;
}

int s2n_stuffer_read_hex(struct s2n_stuffer *stuffer, struct s2n_stuffer *out, uint32_t n)
{
    gte_check(s2n_stuffer_space_remaining(out), n);

    for (int i = 0; i < n; i++) {
        uint8_t c;
        GUARD(s2n_stuffer_read_uint8_hex(stuffer, &c));
        GUARD(s2n_stuffer_write_uint8(out, c));
    }

    return 0;
}