Beispiel #1
0
int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
{
    int bl;
    if (in->nlast_block == -1)
        return 0;
    if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx))
        return 0;
    bl = EVP_CIPHER_CTX_block_size(&in->cctx);
    sgx_memcpy(out->k1, in->k1, bl);
    sgx_memcpy(out->k2, in->k2, bl);
    sgx_memcpy(out->tbl, in->tbl, bl);
    sgx_memcpy(out->last_block, in->last_block, bl);
    out->nlast_block = in->nlast_block;
    return 1;
}
Beispiel #2
0
static int sig_out(BIO *b)
{
    BIO_OK_CTX *ctx;
    EVP_MD_CTX *md;

    ctx = b->ptr;
    md = &ctx->md;

    if (ctx->buf_len + 2 * md->digest->md_size > OK_BLOCK_SIZE)
        return 1;

    if (!EVP_DigestInit_ex(md, md->digest, NULL))
        goto berr;
    /*
     * FIXME: there's absolutely no guarantee this makes any sense at all,
     * particularly now EVP_MD_CTX has been restructured.
     */
    RAND_pseudo_bytes(md->md_data, md->digest->md_size);
    sgx_memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size);
    longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
    ctx->buf_len += md->digest->md_size;

    if (!EVP_DigestUpdate(md, WELLKNOWN, sgx_strlen(WELLKNOWN)))
        goto berr;
    if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
        goto berr;
    ctx->buf_len += md->digest->md_size;
    ctx->blockout = 1;
    ctx->sigio = 0;
    return 1;
 berr:
    BIO_clear_retry_flags(b);
    return 0;
}
Beispiel #3
0
_STACK *sk_dup(_STACK *sk)
{
    _STACK *ret;
    char **s;

    if ((ret = sk_new(sk->comp)) == NULL)
        goto err;
    s = (char **)OPENSSL_realloc((char *)ret->data,
                                 (unsigned int)sizeof(char *) *
                                 sk->num_alloc);
    if (s == NULL)
        goto err;
    ret->data = s;

    ret->num = sk->num;
    sgx_memcpy(ret->data, sk->data, sizeof(char *) * sk->num);
    ret->sorted = sk->sorted;
    ret->num_alloc = sk->num_alloc;
    ret->comp = sk->comp;
    return (ret);
 err:
    if (ret)
        sk_free(ret);
    return (NULL);
}
Beispiel #4
0
static int dlfcn_pathbyaddr(void *addr, char *path, int sz)
{
    return 0;
#if 0
# ifdef HAVE_DLINFO
    Dl_info dli;
    int len;

    if (addr == NULL) {
        union {
            int (*f) (void *, char *, int);
            void *p;
        } t = {
            dlfcn_pathbyaddr
        };
        addr = t.p;
    }

    if (dladdr(addr, &dli)) {
        len = (int)strlen(dli.dli_fname);
        if (sz <= 0)
            return len + 1;
        if (len >= sz)
            len = sz - 1;
        sgx_memcpy(path, dli.dli_fname, len);
        path[len++] = 0;
        return len;
    }

    ERR_add_error_data(2, "dlfcn_pathbyaddr(): ", dlerror());
# endif
    return -1;
#endif
}
Beispiel #5
0
static int dl_pathbyaddr(void *addr, char *path, int sz)
{
    struct shl_descriptor inf;
    int i, len;

    if (addr == NULL) {
        union {
            int (*f) (void *, char *, int);
            void *p;
        } t = {
            dl_pathbyaddr
        };
        addr = t.p;
    }

    for (i = -1; shl_get_r(i, &inf) == 0; i++) {
        if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) ||
            ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend)) {
            len = (int)strlen(inf.filename);
            if (sz <= 0)
                return len + 1;
            if (len >= sz)
                len = sz - 1;
            sgx_memcpy(path, inf.filename, len);
            path[len++] = 0;
            return len;
        }
    }

    return -1;
}
Beispiel #6
0
ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
                                     const unsigned char **pp, long len)
{
    ASN1_BIT_STRING *ret = NULL;
    const unsigned char *p;
    unsigned char *s;
    int i;

    if (len < 1) {
        i = ASN1_R_STRING_TOO_SHORT;
        goto err;
    }

    if ((a == NULL) || ((*a) == NULL)) {
        if ((ret = M_ASN1_BIT_STRING_new()) == NULL)
            return (NULL);
    } else
        ret = (*a);

    p = *pp;
    i = *(p++);
    if (i > 7) {
        i = ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
        goto err;
    }
    /*
     * We do this to preserve the settings.  If we modify the settings, via
     * the _set_bit function, we will recalculate on output
     */
    ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
    ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */

    if (len-- > 1) {            /* using one because of the bits left byte */
        s = (unsigned char *)OPENSSL_malloc((int)len);
        if (s == NULL) {
            i = ERR_R_MALLOC_FAILURE;
            goto err;
        }
        sgx_memcpy(s, p, (int)len);
        s[len - 1] &= (0xff << i);
        p += len;
    } else
        s = NULL;

    ret->length = (int)len;
    if (ret->data != NULL)
        OPENSSL_free(ret->data);
    ret->data = s;
    ret->type = V_ASN1_BIT_STRING;
    if (a != NULL)
        (*a) = ret;
    *pp = p;
    return (ret);
 err:
    ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i);
    if ((ret != NULL) && ((a == NULL) || (*a != ret)))
        M_ASN1_BIT_STRING_free(ret);
    return (NULL);
}
Beispiel #7
0
/*
 * Three IO functions for sending data to memory, a BIO and and a FILE
 * pointer.
 */
#if 0                           /* never used */
static int send_mem_chars(void *arg, const void *buf, int len)
{
    unsigned char **out = arg;
    if (!out)
        return 1;
    sgx_memcpy(*out, buf, len);
    *out += len;
    return 1;
}
Beispiel #8
0
int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
{
    int ret, j, bits, len;
    unsigned char *p, *d;

    if (a == NULL)
        return (0);

    len = a->length;

    if (len > 0) {
        if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
            bits = (int)a->flags & 0x07;
        } else {
            for (; len > 0; len--) {
                if (a->data[len - 1])
                    break;
            }
            j = a->data[len - 1];
            if (j & 0x01)
                bits = 0;
            else if (j & 0x02)
                bits = 1;
            else if (j & 0x04)
                bits = 2;
            else if (j & 0x08)
                bits = 3;
            else if (j & 0x10)
                bits = 4;
            else if (j & 0x20)
                bits = 5;
            else if (j & 0x40)
                bits = 6;
            else if (j & 0x80)
                bits = 7;
            else
                bits = 0;       /* should not happen */
        }
    } else
        bits = 0;

    ret = 1 + len;
    if (pp == NULL)
        return (ret);

    p = *pp;

    *(p++) = (unsigned char)bits;
    d = a->data;
    sgx_memcpy(p, d, len);
    p += len;
    if (len > 0)
        p[-1] &= (0xff << bits);
    *pp = p;
    return (ret);
}
Beispiel #9
0
void sgx_debug(char msg[])
{
    size_t size = sgx_strlen(msg);
    sgx_stub_info_tp *stub = (sgx_stub_info_tp *)STUB_ADDR_TP;

    stub->fcode = FUNC_DEBUG;
    sgx_memcpy(stub->out_data1, msg, size);

    sgx_exit(stub->trampoline);
}
Beispiel #10
0
void sgx_print_bytes(char *s, size_t n)
{
    sgx_stub_info_tp *stub = (sgx_stub_info_tp *)STUB_ADDR_TP;

    stub->fcode = FUNC_PRINT_BYTES;
    sgx_memcpy(stub->out_data1, s, n);
    stub->out_arg1 = n;

    sgx_exit(stub->trampoline);
}
Beispiel #11
0
int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
{
    const unsigned char *data = in;
    size_t bl;
#ifdef OPENSSL_FIPS
    if (FIPS_mode() && !ctx->cctx.engine)
        return FIPS_cmac_update(ctx, in, dlen);
#endif
    if (ctx->nlast_block == -1)
        return 0;
    if (dlen == 0)
        return 1;
    bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
    /* Copy into partial block if we need to */
    if (ctx->nlast_block > 0) {
        size_t nleft;
        nleft = bl - ctx->nlast_block;
        if (dlen < nleft)
            nleft = dlen;
        sgx_memcpy(ctx->last_block + ctx->nlast_block, data, nleft);
        dlen -= nleft;
        ctx->nlast_block += nleft;
        /* If no more to process return */
        if (dlen == 0)
            return 1;
        data += nleft;
        /* Else not final block so encrypt it */
        if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block, bl))
            return 0;
    }
    /* Encrypt all but one of the complete blocks left */
    while (dlen > bl) {
        if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl))
            return 0;
        dlen -= bl;
        data += bl;
    }
    /* Copy any data left to last block buffer */
    sgx_memcpy(ctx->last_block, data, dlen);
    ctx->nlast_block = dlen;
    return 1;

}
Beispiel #12
0
static void run_cert(X509 *crt, const char *nameincert,
                     const struct set_name_fn *fn)
{
    const char *const *pname = names;
    while (*pname) {
        int samename = sgx_strcasecmp(nameincert, *pname) == 0;
        size_t namelen = sgx_strlen(*pname);
        char *name = sgx_malloc(namelen);
        int match, ret;
        sgx_memcpy(name, *pname, namelen);

        ret = X509_check_host(crt, name, namelen, 0, NULL);
        match = -1;
        if (ret < 0) {
            fprintf(stderr, "internal error in X509_check_host");
            ++errors;
        } else if (fn->host) {
            if (ret == 1 && !samename)
                match = 1;
            if (ret == 0 && samename)
                match = 0;
        } else if (ret == 1)
            match = 1;
        check_message(fn, "host", nameincert, match, *pname);

        ret = X509_check_host(crt, name, namelen,
                              X509_CHECK_FLAG_NO_WILDCARDS, NULL);
        match = -1;
        if (ret < 0) {
            fprintf(stderr, "internal error in X509_check_host");
            ++errors;
        } else if (fn->host) {
            if (ret == 1 && !samename)
                match = 1;
            if (ret == 0 && samename)
                match = 0;
        } else if (ret == 1)
            match = 1;
        check_message(fn, "host-no-wildcards", nameincert, match, *pname);

        ret = X509_check_email(crt, name, namelen, 0);
        match = -1;
        if (fn->email) {
            if (ret && !samename)
                match = 1;
            if (!ret && samename && sgx_strchr(nameincert, '@') != NULL)
                match = 0;
        } else if (ret)
            match = 1;
        check_message(fn, "email", nameincert, match, *pname);
        ++pname;
        sgx_free(name);
    }
}
Beispiel #13
0
/* int max_len:  for returned value    */
int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num,
                                  unsigned char *data, int max_len)
{
    int ret = -1, n;
    ASN1_INTEGER *ai = NULL;
    ASN1_OCTET_STRING *os = NULL;
    const unsigned char *p;
    long length;
    ASN1_const_CTX c;

    if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) {
        goto err;
    }
    p = M_ASN1_STRING_data(a->value.sequence);
    length = M_ASN1_STRING_length(a->value.sequence);

    c.pp = &p;
    c.p = p;
    c.max = p + length;
    c.error = ASN1_R_DATA_IS_WRONG;

    M_ASN1_D2I_start_sequence();
    c.q = c.p;
    if ((ai = d2i_ASN1_INTEGER(NULL, &c.p, c.slen)) == NULL)
        goto err;
    c.slen -= (c.p - c.q);
    c.q = c.p;
    if ((os = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL)
        goto err;
    c.slen -= (c.p - c.q);
    if (!M_ASN1_D2I_end_sequence())
        goto err;

    if (num != NULL)
        *num = ASN1_INTEGER_get(ai);

    ret = M_ASN1_STRING_length(os);
    if (max_len > ret)
        n = ret;
    else
        n = max_len;

    if (data != NULL)
        sgx_memcpy(data, M_ASN1_STRING_data(os), n);
    if (0) {
 err:
        ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
    }
    if (os != NULL)
        M_ASN1_OCTET_STRING_free(os);
    if (ai != NULL)
        M_ASN1_INTEGER_free(ai);
    return (ret);
}
Beispiel #14
0
struct tm *tor_gmtime_r(const time_t *timep, struct tm *result)
{
  struct tm *r;
//  assert(result);

  r = sgx_gmtime(timep);
  if (r)
    sgx_memcpy(result, r, sizeof(struct tm));

  return result;
//  return correct_tm(0, timep, result, r);
}
Beispiel #15
0
int RSA_padding_check_none(unsigned char *to, int tlen,
                           const unsigned char *from, int flen, int num)
{

    if (flen > tlen) {
        RSAerr(RSA_F_RSA_PADDING_CHECK_NONE, RSA_R_DATA_TOO_LARGE);
        return (-1);
    }

    sgx_memset(to, 0, tlen - flen);
    sgx_memcpy(to + tlen - flen, from, flen);
    return (tlen);
}
Beispiel #16
0
struct tm *sgx_gmtime(const time_t *timep)
{
    sgx_stub_info_tp *stub = (sgx_stub_info_tp *)STUB_ADDR_TP;
    struct tm temp_tm;

    stub->fcode = FUNC_GMTIME;
    stub->out_arg4 = *timep;
    
    sgx_exit(stub->trampoline);
    sgx_memcpy(&temp_tm, &stub->in_tm, sizeof(struct tm));

    return &temp_tm;
}
Beispiel #17
0
int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
                     const ASN1_ITEM *it)
{
    ASN1_ENCODING *enc;
    enc = asn1_get_enc_ptr(pval, it);
    if (!enc || enc->modified)
        return 0;
    if (out) {
        sgx_memcpy(*out, enc->enc, enc->len);
        *out += enc->len;
    }
    if (len)
        *len = enc->len;
    return 1;
}
Beispiel #18
0
int RSA_padding_add_none(unsigned char *to, int tlen,
                         const unsigned char *from, int flen)
{
    if (flen > tlen) {
        RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
        return (0);
    }

    if (flen < tlen) {
        RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
        return (0);
    }

    sgx_memcpy(to, from, (unsigned int)flen);
    return (1);
}
Beispiel #19
0
/* int max_len:  for returned value    */
int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len)
{
    int ret, num;
    unsigned char *p;

    if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL)) {
        ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
        return (-1);
    }
    p = M_ASN1_STRING_data(a->value.octet_string);
    ret = M_ASN1_STRING_length(a->value.octet_string);
    if (ret < max_len)
        num = ret;
    else
        num = max_len;
    sgx_memcpy(data, p, num);
    return (ret);
}
Beispiel #20
0
int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
                  const ASN1_ITEM *it)
{
    ASN1_ENCODING *enc;
    enc = asn1_get_enc_ptr(pval, it);
    if (!enc)
        return 1;

    if (enc->enc)
        OPENSSL_free(enc->enc);
    enc->enc = OPENSSL_malloc(inlen);
    if (!enc->enc)
        return 0;
    sgx_memcpy(enc->enc, in, inlen);
    enc->len = inlen;
    enc->modified = 0;

    return 1;
}
Beispiel #21
0
/** Helper function to implement crypto_pk_write_*_key_to_string. */
int crypto_pk_write_key_to_string_impl(crypto_pk_t *env, char **dest,
                                   size_t *len, int is_public)
{
    BUF_MEM *buf;
    BIO *b;
    int r;

//    assert(env);
//    assert(env->key);
//    assert(dest);

    b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
    if (!b)
        return -1;

    /* Now you can treat b as if it were a file.  Just use the
     * PEM_*_bio_* functions instead of the non-bio variants.
     */
    if (is_public)
        r = PEM_write_bio_RSAPublicKey(b, env->key);
    else
        r = PEM_write_bio_RSAPrivateKey(b, env->key, NULL,NULL,0,NULL,NULL);

    if (!r) {
        err(1, "writing RSA key to string");
        BIO_free(b);
        return -1;
    }

    BIO_get_mem_ptr(b, &buf);
    (void)BIO_set_close(b, BIO_NOCLOSE); /* so BIO_free doesn't free buf */
    BIO_free(b);

    *dest = sgx_malloc(buf->length+1);
    sgx_memcpy(*dest, buf->data, buf->length);
    (*dest)[buf->length] = 0; /* nul terminate it */
    *len = buf->length;
    BUF_MEM_free(buf);

    return 0;
}
Beispiel #22
0
static int sig_in(BIO *b)
{
    BIO_OK_CTX *ctx;
    EVP_MD_CTX *md;
    unsigned char tmp[EVP_MAX_MD_SIZE];
    int ret = 0;

    ctx = b->ptr;
    md = &ctx->md;

    if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md->digest->md_size)
        return 1;

    if (!EVP_DigestInit_ex(md, md->digest, NULL))
        goto berr;
    sgx_memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size);
    longswap(md->md_data, md->digest->md_size);
    ctx->buf_off += md->digest->md_size;

    if (!EVP_DigestUpdate(md, WELLKNOWN, sgx_strlen(WELLKNOWN)))
        goto berr;
    if (!EVP_DigestFinal_ex(md, tmp, NULL))
        goto berr;
    ret = sgx_memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0;
    ctx->buf_off += md->digest->md_size;
    if (ret == 1) {
        ctx->sigio = 0;
        if (ctx->buf_len != ctx->buf_off) {
            sgx_memmove(ctx->buf, &(ctx->buf[ctx->buf_off]),
                    ctx->buf_len - ctx->buf_off);
        }
        ctx->buf_len -= ctx->buf_off;
        ctx->buf_off = 0;
    } else {
        ctx->cont = 0;
    }
    return 1;
 berr:
    BIO_clear_retry_flags(b);
    return 0;
}
Beispiel #23
0
int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
                           size_t serverinfo_length)
{
    if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    if (!serverinfo_process_buffer(serverinfo, serverinfo_length, NULL)) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA);
        return 0;
    }
    if (!ssl_cert_inst(&ctx->cert)) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    if (ctx->cert->key == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_INTERNAL_ERROR);
        return 0;
    }
    ctx->cert->key->serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo,
                                                 serverinfo_length);
    if (ctx->cert->key->serverinfo == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    sgx_memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length);
    ctx->cert->key->serverinfo_length = serverinfo_length;

    /*
     * Now that the serverinfo is validated and stored, go ahead and
     * register callbacks.
     */
    if (!serverinfo_process_buffer(serverinfo, serverinfo_length, ctx)) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA);
        return 0;
    }
    return 1;
}
Beispiel #24
0
/*
 * AES-CMAC-128 process message
 */
void sgx_aes_cmac128_update(aes_cmac128_context *ctx, const uint8_t *_msg, size_t _msg_len)
{
    unsigned char iv[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    uint8_t tmp_block[16];
    uint8_t Y[16];
    const uint8_t *msg = _msg;
    size_t msg_len = _msg_len;

    /*
     * copy the remembered last block
     */
    ZERO_STRUCT(tmp_block);
    if (ctx->last_len) {
        sgx_memcpy(tmp_block, ctx->last, ctx->last_len);
    }

    /*
     * check if we expand the block
     */
    if (ctx->last_len < 16) {
        size_t len = MIN(16 - ctx->last_len, msg_len);

        sgx_memcpy(&tmp_block[ctx->last_len], msg, len);
        sgx_memcpy(ctx->last, tmp_block, 16);
        msg += len;
        msg_len -= len;
        ctx->last_len += len;
    }

    if (msg_len == 0) {
        /* if it is still the last block, we are done */
        ZERO_STRUCT(tmp_block);
        return;
    }

    /*
     * It is not the last block anymore
     */
    ZERO_STRUCT(ctx->last);
    ctx->last_len = 0;

    /*
     * now checksum everything but the last block
     */
    sgx_aes_cmac_128_xor(ctx->X, tmp_block, Y);
    sgx_aes_crypt_cbc(&ctx->aes_key, AES_ENCRYPT, 16, iv, Y, ctx->X);

    while (msg_len > 16) {
        sgx_memcpy(tmp_block, msg, 16);
        msg += 16;
        msg_len -= 16;

        sgx_aes_cmac_128_xor(ctx->X, tmp_block, Y);
        sgx_aes_crypt_cbc(&ctx->aes_key, AES_ENCRYPT, 16, iv, Y, ctx->X);
    }

    /*
     * copy the last block, it will be processed in
     * aes_cmac128_final().
     */
    sgx_memcpy(ctx->last, msg, msg_len);
    ctx->last_len = msg_len;

    ZERO_STRUCT(tmp_block);
    ZERO_STRUCT(Y);
}
Beispiel #25
0
void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
                     size_t length, const AES_KEY *key,
                     unsigned char *ivec, const int enc)
{
    size_t n;
    size_t len = length;

    OPENSSL_assert(in && out && key && ivec);
    OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
    OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);

    len = length / AES_BLOCK_SIZE;

    if (AES_ENCRYPT == enc) {
        if (in != out &&
            (UNALIGNED_MEMOPS_ARE_FAST
             || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) ==
             0)) {
            aes_block_t *ivp = (aes_block_t *) ivec;
            aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE);

            while (len) {
                aes_block_t *inp = (aes_block_t *) in;
                aes_block_t *outp = (aes_block_t *) out;

                for (n = 0; n < N_WORDS; ++n)
                    outp->data[n] = inp->data[n] ^ ivp->data[n];
                AES_encrypt((unsigned char *)outp->data,
                            (unsigned char *)outp->data, key);
                for (n = 0; n < N_WORDS; ++n)
                    outp->data[n] ^= iv2p->data[n];
                ivp = outp;
                iv2p = inp;
                --len;
                in += AES_BLOCK_SIZE;
                out += AES_BLOCK_SIZE;
            }
            sgx_memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
            sgx_memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
        } else {
            aes_block_t tmp, tmp2;
            aes_block_t iv;
            aes_block_t iv2;

            load_block(iv, ivec);
            load_block(iv2, ivec + AES_BLOCK_SIZE);

            while (len) {
                load_block(tmp, in);
                for (n = 0; n < N_WORDS; ++n)
                    tmp2.data[n] = tmp.data[n] ^ iv.data[n];
                AES_encrypt((unsigned char *)tmp2.data,
                            (unsigned char *)tmp2.data, key);
                for (n = 0; n < N_WORDS; ++n)
                    tmp2.data[n] ^= iv2.data[n];
                store_block(out, tmp2);
                iv = tmp2;
                iv2 = tmp;
                --len;
                in += AES_BLOCK_SIZE;
                out += AES_BLOCK_SIZE;
            }
            sgx_memcpy(ivec, iv.data, AES_BLOCK_SIZE);
            sgx_memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
        }
    } else {
        if (in != out &&
            (UNALIGNED_MEMOPS_ARE_FAST
             || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) ==
             0)) {
            aes_block_t *ivp = (aes_block_t *) ivec;
            aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE);

            while (len) {
                aes_block_t tmp;
                aes_block_t *inp = (aes_block_t *) in;
                aes_block_t *outp = (aes_block_t *) out;

                for (n = 0; n < N_WORDS; ++n)
                    tmp.data[n] = inp->data[n] ^ iv2p->data[n];
                AES_decrypt((unsigned char *)tmp.data,
                            (unsigned char *)outp->data, key);
                for (n = 0; n < N_WORDS; ++n)
                    outp->data[n] ^= ivp->data[n];
                ivp = inp;
                iv2p = outp;
                --len;
                in += AES_BLOCK_SIZE;
                out += AES_BLOCK_SIZE;
            }
            sgx_memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
            sgx_memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
        } else {
            aes_block_t tmp, tmp2;
            aes_block_t iv;
            aes_block_t iv2;

            load_block(iv, ivec);
            load_block(iv2, ivec + AES_BLOCK_SIZE);

            while (len) {
                load_block(tmp, in);
                tmp2 = tmp;
                for (n = 0; n < N_WORDS; ++n)
                    tmp.data[n] ^= iv2.data[n];
                AES_decrypt((unsigned char *)tmp.data,
                            (unsigned char *)tmp.data, key);
                for (n = 0; n < N_WORDS; ++n)
                    tmp.data[n] ^= iv.data[n];
                store_block(out, tmp);
                iv = tmp2;
                iv2 = tmp;
                --len;
                in += AES_BLOCK_SIZE;
                out += AES_BLOCK_SIZE;
            }
            sgx_memcpy(ivec, iv.data, AES_BLOCK_SIZE);
            sgx_memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
        }
    }
}
Beispiel #26
0
void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
                        size_t length, const AES_KEY *key,
                        const AES_KEY *key2, const unsigned char *ivec,
                        const int enc)
{
    size_t n;
    size_t len = length;
    unsigned char tmp[AES_BLOCK_SIZE];
    unsigned char tmp2[AES_BLOCK_SIZE];
    unsigned char tmp3[AES_BLOCK_SIZE];
    unsigned char prev[AES_BLOCK_SIZE];
    const unsigned char *iv;
    const unsigned char *iv2;

    OPENSSL_assert(in && out && key && ivec);
    OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
    OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);

    if (AES_ENCRYPT == enc) {
        /*
         * XXX: Do a separate case for when in != out (strictly should check
         * for overlap, too)
         */

        /* First the forward pass */
        iv = ivec;
        iv2 = ivec + AES_BLOCK_SIZE;
        while (len >= AES_BLOCK_SIZE) {
            for (n = 0; n < AES_BLOCK_SIZE; ++n)
                out[n] = in[n] ^ iv[n];
            AES_encrypt(out, out, key);
            for (n = 0; n < AES_BLOCK_SIZE; ++n)
                out[n] ^= iv2[n];
            iv = out;
            sgx_memcpy(prev, in, AES_BLOCK_SIZE);
            iv2 = prev;
            len -= AES_BLOCK_SIZE;
            in += AES_BLOCK_SIZE;
            out += AES_BLOCK_SIZE;
        }

        /* And now backwards */
        iv = ivec + AES_BLOCK_SIZE * 2;
        iv2 = ivec + AES_BLOCK_SIZE * 3;
        len = length;
        while (len >= AES_BLOCK_SIZE) {
            out -= AES_BLOCK_SIZE;
            /*
             * XXX: reduce copies by alternating between buffers
             */
            sgx_memcpy(tmp, out, AES_BLOCK_SIZE);
            for (n = 0; n < AES_BLOCK_SIZE; ++n)
                out[n] ^= iv[n];
            /*
             * hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE);
             */
            AES_encrypt(out, out, key);
            /*
             * hexdump(stdout,"enc", out, AES_BLOCK_SIZE);
             */
            /*
             * hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE);
             */
            for (n = 0; n < AES_BLOCK_SIZE; ++n)
                out[n] ^= iv2[n];
            /*
             * hexdump(stdout,"out", out, AES_BLOCK_SIZE);
             */
            iv = out;
            sgx_memcpy(prev, tmp, AES_BLOCK_SIZE);
            iv2 = prev;
            len -= AES_BLOCK_SIZE;
        }
    } else {
        /* First backwards */
        iv = ivec + AES_BLOCK_SIZE * 2;
        iv2 = ivec + AES_BLOCK_SIZE * 3;
        in += length;
        out += length;
        while (len >= AES_BLOCK_SIZE) {
            in -= AES_BLOCK_SIZE;
            out -= AES_BLOCK_SIZE;
            sgx_memcpy(tmp, in, AES_BLOCK_SIZE);
            sgx_memcpy(tmp2, in, AES_BLOCK_SIZE);
            for (n = 0; n < AES_BLOCK_SIZE; ++n)
                tmp[n] ^= iv2[n];
            AES_decrypt(tmp, out, key);
            for (n = 0; n < AES_BLOCK_SIZE; ++n)
                out[n] ^= iv[n];
            sgx_memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
            iv = tmp3;
            iv2 = out;
            len -= AES_BLOCK_SIZE;
        }

        /* And now forwards */
        iv = ivec;
        iv2 = ivec + AES_BLOCK_SIZE;
        len = length;
        while (len >= AES_BLOCK_SIZE) {
            sgx_memcpy(tmp, out, AES_BLOCK_SIZE);
            sgx_memcpy(tmp2, out, AES_BLOCK_SIZE);
            for (n = 0; n < AES_BLOCK_SIZE; ++n)
                tmp[n] ^= iv2[n];
            AES_decrypt(tmp, out, key);
            for (n = 0; n < AES_BLOCK_SIZE; ++n)
                out[n] ^= iv[n];
            sgx_memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
            iv = tmp3;
            iv2 = out;
            len -= AES_BLOCK_SIZE;
            in += AES_BLOCK_SIZE;
            out += AES_BLOCK_SIZE;
        }
    }
}
Beispiel #27
0
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
                              unsigned char *salt, int saltlen,
                              unsigned char *aiv, int prf_nid)
{
    X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
    int alg_nid, keylen;
    EVP_CIPHER_CTX ctx;
    unsigned char iv[EVP_MAX_IV_LENGTH];
    PBE2PARAM *pbe2 = NULL;
    ASN1_OBJECT *obj;

    alg_nid = EVP_CIPHER_type(cipher);
    if (alg_nid == NID_undef) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
        goto err;
    }
    obj = OBJ_nid2obj(alg_nid);

    if (!(pbe2 = PBE2PARAM_new()))
        goto merr;

    /* Setup the AlgorithmIdentifier for the encryption scheme */
    scheme = pbe2->encryption;

    scheme->algorithm = obj;
    if (!(scheme->parameter = ASN1_TYPE_new()))
        goto merr;

    /* Create random IV */
    if (EVP_CIPHER_iv_length(cipher)) {
        if (aiv)
            sgx_memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
        else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
            goto err;
    }

    EVP_CIPHER_CTX_init(&ctx);

    /* Dummy cipherinit to just setup the IV, and PRF */
    if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
        goto err;
    if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
        EVP_CIPHER_CTX_cleanup(&ctx);
        goto err;
    }
    /*
     * If prf NID unspecified see if cipher has a preference. An error is OK
     * here: just means use default PRF.
     */
    if ((prf_nid == -1) &&
        EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) {
        ERR_clear_error();
        prf_nid = NID_hmacWithSHA1;
    }
    EVP_CIPHER_CTX_cleanup(&ctx);

    /* If its RC2 then we'd better setup the key length */

    if (alg_nid == NID_rc2_cbc)
        keylen = EVP_CIPHER_key_length(cipher);
    else
        keylen = -1;

    /* Setup keyfunc */

    X509_ALGOR_free(pbe2->keyfunc);

    pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);

    if (!pbe2->keyfunc)
        goto merr;

    /* Now set up top level AlgorithmIdentifier */

    if (!(ret = X509_ALGOR_new()))
        goto merr;
    if (!(ret->parameter = ASN1_TYPE_new()))
        goto merr;

    ret->algorithm = OBJ_nid2obj(NID_pbes2);

    /* Encode PBE2PARAM into parameter */

    if (!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
                        &ret->parameter->value.sequence))
         goto merr;
    ret->parameter->type = V_ASN1_SEQUENCE;

    PBE2PARAM_free(pbe2);
    pbe2 = NULL;

    return ret;

 merr:
    ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE);

 err:
    PBE2PARAM_free(pbe2);
    /* Note 'scheme' is freed as part of pbe2 */
    X509_ALGOR_free(kalg);
    X509_ALGOR_free(ret);

    return NULL;

}
Beispiel #28
0
ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
{
    ASN1_TYPE *ret;
    tag_exp_arg asn1_tags;
    tag_exp_type *etmp;

    int i, len;

    unsigned char *orig_der = NULL, *new_der = NULL;
    const unsigned char *cpy_start;
    unsigned char *p;
    const unsigned char *cp;
    int cpy_len;
    long hdr_len;
    int hdr_constructed = 0, hdr_tag, hdr_class;
    int r;

    asn1_tags.imp_tag = -1;
    asn1_tags.imp_class = -1;
    asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
    asn1_tags.exp_count = 0;
    if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
        return NULL;

    if ((asn1_tags.utype == V_ASN1_SEQUENCE)
        || (asn1_tags.utype == V_ASN1_SET)) {
        if (!cnf) {
            ASN1err(ASN1_F_ASN1_GENERATE_V3,
                    ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
            return NULL;
        }
        ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
    } else
        ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);

    if (!ret)
        return NULL;

    /* If no tagging return base type */
    if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
        return ret;

    /* Generate the encoding */
    cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
    ASN1_TYPE_free(ret);
    ret = NULL;
    /* Set point to start copying for modified encoding */
    cpy_start = orig_der;

    /* Do we need IMPLICIT tagging? */
    if (asn1_tags.imp_tag != -1) {
        /* If IMPLICIT we will replace the underlying tag */
        /* Skip existing tag+len */
        r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class,
                            cpy_len);
        if (r & 0x80)
            goto err;
        /* Update copy length */
        cpy_len -= cpy_start - orig_der;
        /*
         * For IMPLICIT tagging the length should match the original length
         * and constructed flag should be consistent.
         */
        if (r & 0x1) {
            /* Indefinite length constructed */
            hdr_constructed = 2;
            hdr_len = 0;
        } else
            /* Just retain constructed flag */
            hdr_constructed = r & V_ASN1_CONSTRUCTED;
        /*
         * Work out new length with IMPLICIT tag: ignore constructed because
         * it will mess up if indefinite length
         */
        len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
    } else
        len = cpy_len;

    /* Work out length in any EXPLICIT, starting from end */

    for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1;
         i < asn1_tags.exp_count; i++, etmp--) {
        /* Content length: number of content octets + any padding */
        len += etmp->exp_pad;
        etmp->exp_len = len;
        /* Total object length: length including new header */
        len = ASN1_object_size(0, len, etmp->exp_tag);
    }

    /* Allocate buffer for new encoding */

    new_der = OPENSSL_malloc(len);
    if (!new_der)
        goto err;

    /* Generate tagged encoding */

    p = new_der;

    /* Output explicit tags first */

    for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count;
         i++, etmp++) {
        ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
                        etmp->exp_tag, etmp->exp_class);
        if (etmp->exp_pad)
            *p++ = 0;
    }

    /* If IMPLICIT, output tag */

    if (asn1_tags.imp_tag != -1) {
        if (asn1_tags.imp_class == V_ASN1_UNIVERSAL
            && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
                || asn1_tags.imp_tag == V_ASN1_SET))
            hdr_constructed = V_ASN1_CONSTRUCTED;
        ASN1_put_object(&p, hdr_constructed, hdr_len,
                        asn1_tags.imp_tag, asn1_tags.imp_class);
    }

    /* Copy across original encoding */
    sgx_memcpy(p, cpy_start, cpy_len);

    cp = new_der;

    /* Obtain new ASN1_TYPE structure */
    ret = d2i_ASN1_TYPE(NULL, &cp, len);

 err:
    if (orig_der)
        OPENSSL_free(orig_der);
    if (new_der)
        OPENSSL_free(new_der);

    return ret;

}
Beispiel #29
0
int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
{
    unsigned char *serverinfo = NULL;
    size_t serverinfo_length = 0;
    unsigned char *extension = 0;
    long extension_length = 0;
    char *name = NULL;
    char *header = NULL;
    char namePrefix[] = "SERVERINFO FOR ";
    int ret = 0;
    BIO *bin = NULL;
    size_t num_extensions = 0;

    if (ctx == NULL || file == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,
               ERR_R_PASSED_NULL_PARAMETER);
        goto end;
    }

    bin = BIO_new(BIO_s_file_internal());
    if (bin == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_BUF_LIB);
        goto end;
    }
    if (BIO_read_filename(bin, file) <= 0) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_SYS_LIB);
        goto end;
    }

    for (num_extensions = 0;; num_extensions++) {
        if (PEM_read_bio(bin, &name, &header, &extension, &extension_length)
            == 0) {
            /*
             * There must be at least one extension in this file
             */
            if (num_extensions == 0) {
                SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,
                       SSL_R_NO_PEM_EXTENSIONS);
                goto end;
            } else              /* End of file, we're done */
                break;
        }
        /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */
        if (sgx_strlen(name) < sgx_strlen(namePrefix)) {
            SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,
                   SSL_R_PEM_NAME_TOO_SHORT);
            goto end;
        }
        if (sgx_strncmp(name, namePrefix, sgx_strlen(namePrefix)) != 0) {
            SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,
                   SSL_R_PEM_NAME_BAD_PREFIX);
            goto end;
        }
        /*
         * Check that the decoded PEM data is plausible (valid length field)
         */
        if (extension_length < 4
            || (extension[2] << 8) + extension[3] != extension_length - 4) {
            SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA);
            goto end;
        }
        /* Append the decoded extension to the serverinfo buffer */
        serverinfo =
            OPENSSL_realloc(serverinfo, serverinfo_length + extension_length);
        if (serverinfo == NULL) {
            SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE);
            goto end;
        }
        sgx_memcpy(serverinfo + serverinfo_length, extension, extension_length);
        serverinfo_length += extension_length;

        OPENSSL_free(name);
        name = NULL;
        OPENSSL_free(header);
        header = NULL;
        OPENSSL_free(extension);
        extension = NULL;
    }

    ret = SSL_CTX_use_serverinfo(ctx, serverinfo, serverinfo_length);
 end:
    /* SSL_CTX_use_serverinfo makes a local copy of the serverinfo. */
    OPENSSL_free(name);
    OPENSSL_free(header);
    OPENSSL_free(extension);
    OPENSSL_free(serverinfo);
    if (bin != NULL)
        BIO_free(bin);
    return ret;
}
Beispiel #30
0
int DES_enc_write(int fd, const void *_buf, int len,
                  DES_key_schedule *sched, DES_cblock *iv)
{
#if defined(OPENSSL_NO_POSIX_IO)
    return (-1);
#else
# ifdef _LIBC
    extern unsigned long time();
    extern int write();
# endif
    const unsigned char *buf = _buf;
    long rnum;
    int i, j, k, outnum;
    static unsigned char *outbuf = NULL;
    unsigned char shortbuf[8];
    unsigned char *p;
    const unsigned char *cp;
    static int start = 1;

    if (outbuf == NULL) {
        outbuf = OPENSSL_malloc(BSIZE + HDRSIZE);
        if (outbuf == NULL)
            return (-1);
    }
    /*
     * If we are sending less than 8 bytes, the same char will look the same
     * if we don't pad it out with random bytes
     */
    if (start) {
        start = 0;
    }

    /* lets recurse if we want to send the data in small chunks */
    if (len > MAXWRITE) {
        j = 0;
        for (i = 0; i < len; i += k) {
            k = DES_enc_write(fd, &(buf[i]),
                              ((len - i) > MAXWRITE) ? MAXWRITE : (len - i),
                              sched, iv);
            if (k < 0)
                return (k);
            else
                j += k;
        }
        return (j);
    }

    /* write length first */
    p = outbuf;
    l2n(len, p);

    /* pad short strings */
    if (len < 8) {
        cp = shortbuf;
        sgx_memcpy(shortbuf, buf, len);
        RAND_pseudo_bytes(shortbuf + len, 8 - len);
        rnum = 8;
    } else {
        cp = buf;
        rnum = ((len + 7) / 8 * 8); /* round up to nearest eight */
    }

    if (DES_rw_mode & DES_PCBC_MODE)
        DES_pcbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched,
                         iv, DES_ENCRYPT);
    else
        DES_cbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched,
                        iv, DES_ENCRYPT);

    /* output */
    outnum = rnum + HDRSIZE;

    for (j = 0; j < outnum; j += i) {
        /*
         * eay 26/08/92 I was not doing writing from where we got up to.
         */
# ifndef _WIN32
        i = write(fd, (void *)&(outbuf[j]), outnum - j);
# else
        i = _write(fd, (void *)&(outbuf[j]), outnum - j);
# endif
        if (i == -1) {
# ifdef EINTR
            if (errno == EINTR)
                i = 0;
            else
# endif
                /*
                 * This is really a bad error - very bad It will stuff-up
                 * both ends.
                 */
                return (-1);
        }
    }

    return (len);
#endif                          /* OPENSSL_NO_POSIX_IO */
}