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; }
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; }
_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); }
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 }
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; }
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); }
/* * 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; }
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); }
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); }
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); }
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; }
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); } }
/* 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); }
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); }
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); }
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; }
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; }
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); }
/* 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); }
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; }
/** 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; }
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; }
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; }
/* * 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); }
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); } } }
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; } } }
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; }
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; }
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; }
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 */ }