Loading ssl/s3_both.c +8 −4 Original line number Diff line number Diff line Loading @@ -589,13 +589,17 @@ int ssl_verify_alarm_type(long type) int ssl3_setup_buffers(SSL *s) { unsigned char *p; size_t len; size_t len,align=0; #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 align = (-SSL3_RT_HEADER_LENGTH)&(SSL3_ALIGN_PAYLOAD-1); #endif if (s->s3->rbuf.buf == NULL) { len = SSL3_RT_MAX_PLAIN_LENGTH + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + SSL3_RT_HEADER_LENGTH; + SSL3_RT_HEADER_LENGTH + align; if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) { s->s3->init_extra = 1; Loading @@ -615,13 +619,13 @@ int ssl3_setup_buffers(SSL *s) { len = s->max_send_fragment + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + SSL3_RT_HEADER_LENGTH; + SSL3_RT_HEADER_LENGTH + align; #ifndef OPENSSL_NO_COMP if (!(s->options & SSL_OP_NO_COMPRESSION)) len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; #endif if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) len += SSL3_RT_HEADER_LENGTH len += SSL3_RT_HEADER_LENGTH + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; if ((p=OPENSSL_malloc(len)) == NULL) goto err; Loading ssl/s3_pkt.c +100 −48 Original line number Diff line number Diff line Loading @@ -129,14 +129,44 @@ int ssl3_read_n(SSL *s, int n, int max, int extend) * (If s->read_ahead is set, 'max' bytes may be stored in rbuf * [plus s->packet_length bytes if extend == 1].) */ int i,off,newb; int i,len,left,align=0; unsigned char *pkt; SSL3_BUFFER *rb; if (n <= 0) return n; rb = &(s->s3->rbuf); left = rb->left; #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 align = (int)rb->buf + SSL3_RT_HEADER_LENGTH; align = (-align)&(SSL3_ALIGN_PAYLOAD-1); #endif if (!extend) { /* start with empty packet ... */ if (s->s3->rbuf.left == 0) s->s3->rbuf.offset = 0; s->packet = s->s3->rbuf.buf + s->s3->rbuf.offset; if (left == 0) rb->offset = align; else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) { /* check if next packet length is large * enough to justify payload alignment... */ pkt = rb->buf + rb->offset; if (pkt[0] == SSL3_RT_APPLICATION_DATA && (pkt[3]<<8|pkt[4]) >= 128) { /* Note that even if packet is corrupted * and its length field is insane, we can * only be led to wrong decision about * whether memmove will occur or not. * Header values has no effect on memmove * arguments and therefore no buffer * overrun can be triggered. */ memmove (rb->buf+align,pkt,left); rb->offset = align; } } s->packet = rb->buf + rb->offset; s->packet_length = 0; /* ... now we can act as if 'extend' was set */ } Loading @@ -145,57 +175,54 @@ int ssl3_read_n(SSL *s, int n, int max, int extend) if ( SSL_version(s) == DTLS1_VERSION && extend) { if ( s->s3->rbuf.left > 0 && n > s->s3->rbuf.left) n = s->s3->rbuf.left; if ( left > 0 && n > left) n = left; } /* if there is enough in the buffer from a previous read, take some */ if (s->s3->rbuf.left >= (int)n) if (left >= n) { s->packet_length+=n; s->s3->rbuf.left-=n; s->s3->rbuf.offset+=n; rb->left=left-n; rb->offset+=n; return(n); } /* else we need to read more data */ if (!s->read_ahead) max=n; len = s->packet_length; pkt = rb->buf+align; /* Move any available bytes to front of buffer: * 'len' bytes already pointed to by 'packet', * 'left' extra ones at the end */ if (s->packet != pkt) /* len > 0 */ { /* avoid buffer overflow */ int max_max = s->s3->rbuf.len - s->packet_length; if (max > max_max) max = max_max; memmove(pkt, s->packet, len+left); s->packet = pkt; rb->offset = len + align; } max = rb->len - rb->offset; if (n > max) /* does not happen */ { SSLerr(SSL_F_SSL3_READ_N,ERR_R_INTERNAL_ERROR); return -1; } off = s->packet_length; newb = s->s3->rbuf.left; /* Move any available bytes to front of buffer: * 'off' bytes already pointed to by 'packet', * 'newb' extra ones at the end */ if (s->packet != s->s3->rbuf.buf) { /* off > 0 */ memmove(s->s3->rbuf.buf, s->packet, off+newb); s->packet = s->s3->rbuf.buf; } if (!s->read_ahead) max=n; while (newb < n) while (left < n) { /* Now we have off+newb bytes at the front of s->s3->rbuf.buf and need * to read in more until we have off+n (up to off+max if possible) */ /* Now we have len+left bytes at the front of s->s3->rbuf.buf * and need to read in more until we have len+n (up to * len+max if possible) */ clear_sys_error(); if (s->rbio != NULL) { s->rwstate=SSL_READING; i=BIO_read(s->rbio, &(s->s3->rbuf.buf[off+newb]), max-newb); i=BIO_read(s->rbio,pkt+len+left, max-left); } else { Loading @@ -205,15 +232,15 @@ int ssl3_read_n(SSL *s, int n, int max, int extend) if (i <= 0) { s->s3->rbuf.left = newb; rb->left = left; return(i); } newb+=i; left+=i; } /* done reading, now the book-keeping */ s->s3->rbuf.offset = off + n; s->s3->rbuf.left = newb - n; rb->offset += n; rb->left = left - n; s->packet_length += n; s->rwstate=SSL_NOTHING; return(n); Loading Loading @@ -579,14 +606,14 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, { unsigned char *p,*plen; int i,mac_size,clear=0; int prefix_len = 0; int prefix_len=0,align=0; SSL3_RECORD *wr; SSL3_BUFFER *wb; SSL3_BUFFER *wb=&(s->s3->wbuf); SSL_SESSION *sess; /* first check if there is a SSL3_BUFFER still being written * out. This will happen with non blocking IO */ if (s->s3->wbuf.left != 0) if (wb->left != 0) return(ssl3_write_pending(s,type,buf,len)); /* If we have an alert to send, lets send it */ Loading @@ -602,7 +629,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, return 0; wr= &(s->s3->wrec); wb= &(s->s3->wbuf); sess=s->session; if ( (sess == NULL) || Loading Loading @@ -643,7 +669,32 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, s->s3->empty_fragment_done = 1; } p = wb->buf + prefix_len; if (create_empty_fragment) { #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 /* extra fragment would be couple of cipher blocks, * which would be multiple of SSL3_ALIGN_PAYLOAD, so * if we want to align the real payload, then we can * just pretent we simply have two headers. */ align = (int)wb->buf + 2*SSL3_RT_HEADER_LENGTH; align = (-align)&(SSL3_ALIGN_PAYLOAD-1); #endif p = wb->buf + align; wb->offset = align; } else if (prefix_len) { p = wb->buf + wb->offset + prefix_len; } else { #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 align = (int)wb->buf + SSL3_RT_HEADER_LENGTH; align = (-align)&(SSL3_ALIGN_PAYLOAD-1); #endif p = wb->buf + align; wb->offset = align; } /* write the header */ Loading Loading @@ -714,7 +765,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* now let's set up wb */ wb->left = prefix_len + wr->length; wb->offset = 0; /* memorize arguments so that ssl3_write_pending can detect bad write retries later */ s->s3->wpend_tot=len; Loading @@ -733,6 +783,7 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, unsigned int len) { int i; SSL3_BUFFER *wb=&(s->s3->wbuf); /* XXXX */ if ((s->s3->wpend_tot > (int)len) Loading @@ -751,24 +802,25 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, { s->rwstate=SSL_WRITING; i=BIO_write(s->wbio, (char *)&(s->s3->wbuf.buf[s->s3->wbuf.offset]), (unsigned int)s->s3->wbuf.left); (char *)&(wb->buf[wb->offset]), (unsigned int)wb->left); } else { SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BIO_NOT_SET); i= -1; } if (i == s->s3->wbuf.left) if (i == wb->left) { s->s3->wbuf.left=0; wb->left=0; wb->offset+=i; s->rwstate=SSL_NOTHING; return(s->s3->wpend_ret); } else if (i <= 0) return(i); s->s3->wbuf.offset+=i; s->s3->wbuf.left-=i; wb->offset+=i; wb->left-=i; } } Loading ssl/ssl3.h +18 −4 Original line number Diff line number Diff line Loading @@ -248,12 +248,27 @@ extern "C" { #define SSL3_SESSION_ID_SIZE 32 #define SSL3_RT_HEADER_LENGTH 5 #ifndef SSL3_ALIGN_PAYLOAD /* Some will argue that this increases memory footprint, but it's * not actually true. Point is that malloc has to return at least * 64-bit aligned pointers, meaning that allocating 5 bytes wastes * 3 bytes in either case. Suggested pre-gaping simply moves these * wasted bytes from the end of allocated region to its front, * but makes data payload aligned, which improves performance:-) */ # define SSL3_ALIGN_PAYLOAD 8 #else # if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0 # error "insane SSL3_ALIGN_PAYLOAD" # undef SSL3_ALIGN_PAYLOAD # endif #endif /* This is the maximum MAC (digest) size used by the SSL library. * Currently this is 20 when SHA1 is used. This must be updated if larger * digests are used in future. * Currently maximum of 20 is used by SHA1, but we reserve for * future extension for 512-bit hashes. */ #define SSL3_RT_MAX_MD_SIZE 20 #define SSL3_RT_MAX_MD_SIZE 64 /* Maximum block size used in all ciphersuites. Currently 16 for AES. */ Loading Loading @@ -292,7 +307,6 @@ extern "C" { (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH) #define SSL3_RT_MAX_PACKET_SIZE \ (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) #define SSL3_RT_MAX_DATA_SIZE (1024*1024) #define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" #define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" Loading Loading
ssl/s3_both.c +8 −4 Original line number Diff line number Diff line Loading @@ -589,13 +589,17 @@ int ssl_verify_alarm_type(long type) int ssl3_setup_buffers(SSL *s) { unsigned char *p; size_t len; size_t len,align=0; #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 align = (-SSL3_RT_HEADER_LENGTH)&(SSL3_ALIGN_PAYLOAD-1); #endif if (s->s3->rbuf.buf == NULL) { len = SSL3_RT_MAX_PLAIN_LENGTH + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + SSL3_RT_HEADER_LENGTH; + SSL3_RT_HEADER_LENGTH + align; if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) { s->s3->init_extra = 1; Loading @@ -615,13 +619,13 @@ int ssl3_setup_buffers(SSL *s) { len = s->max_send_fragment + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + SSL3_RT_HEADER_LENGTH; + SSL3_RT_HEADER_LENGTH + align; #ifndef OPENSSL_NO_COMP if (!(s->options & SSL_OP_NO_COMPRESSION)) len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; #endif if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) len += SSL3_RT_HEADER_LENGTH len += SSL3_RT_HEADER_LENGTH + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; if ((p=OPENSSL_malloc(len)) == NULL) goto err; Loading
ssl/s3_pkt.c +100 −48 Original line number Diff line number Diff line Loading @@ -129,14 +129,44 @@ int ssl3_read_n(SSL *s, int n, int max, int extend) * (If s->read_ahead is set, 'max' bytes may be stored in rbuf * [plus s->packet_length bytes if extend == 1].) */ int i,off,newb; int i,len,left,align=0; unsigned char *pkt; SSL3_BUFFER *rb; if (n <= 0) return n; rb = &(s->s3->rbuf); left = rb->left; #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 align = (int)rb->buf + SSL3_RT_HEADER_LENGTH; align = (-align)&(SSL3_ALIGN_PAYLOAD-1); #endif if (!extend) { /* start with empty packet ... */ if (s->s3->rbuf.left == 0) s->s3->rbuf.offset = 0; s->packet = s->s3->rbuf.buf + s->s3->rbuf.offset; if (left == 0) rb->offset = align; else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) { /* check if next packet length is large * enough to justify payload alignment... */ pkt = rb->buf + rb->offset; if (pkt[0] == SSL3_RT_APPLICATION_DATA && (pkt[3]<<8|pkt[4]) >= 128) { /* Note that even if packet is corrupted * and its length field is insane, we can * only be led to wrong decision about * whether memmove will occur or not. * Header values has no effect on memmove * arguments and therefore no buffer * overrun can be triggered. */ memmove (rb->buf+align,pkt,left); rb->offset = align; } } s->packet = rb->buf + rb->offset; s->packet_length = 0; /* ... now we can act as if 'extend' was set */ } Loading @@ -145,57 +175,54 @@ int ssl3_read_n(SSL *s, int n, int max, int extend) if ( SSL_version(s) == DTLS1_VERSION && extend) { if ( s->s3->rbuf.left > 0 && n > s->s3->rbuf.left) n = s->s3->rbuf.left; if ( left > 0 && n > left) n = left; } /* if there is enough in the buffer from a previous read, take some */ if (s->s3->rbuf.left >= (int)n) if (left >= n) { s->packet_length+=n; s->s3->rbuf.left-=n; s->s3->rbuf.offset+=n; rb->left=left-n; rb->offset+=n; return(n); } /* else we need to read more data */ if (!s->read_ahead) max=n; len = s->packet_length; pkt = rb->buf+align; /* Move any available bytes to front of buffer: * 'len' bytes already pointed to by 'packet', * 'left' extra ones at the end */ if (s->packet != pkt) /* len > 0 */ { /* avoid buffer overflow */ int max_max = s->s3->rbuf.len - s->packet_length; if (max > max_max) max = max_max; memmove(pkt, s->packet, len+left); s->packet = pkt; rb->offset = len + align; } max = rb->len - rb->offset; if (n > max) /* does not happen */ { SSLerr(SSL_F_SSL3_READ_N,ERR_R_INTERNAL_ERROR); return -1; } off = s->packet_length; newb = s->s3->rbuf.left; /* Move any available bytes to front of buffer: * 'off' bytes already pointed to by 'packet', * 'newb' extra ones at the end */ if (s->packet != s->s3->rbuf.buf) { /* off > 0 */ memmove(s->s3->rbuf.buf, s->packet, off+newb); s->packet = s->s3->rbuf.buf; } if (!s->read_ahead) max=n; while (newb < n) while (left < n) { /* Now we have off+newb bytes at the front of s->s3->rbuf.buf and need * to read in more until we have off+n (up to off+max if possible) */ /* Now we have len+left bytes at the front of s->s3->rbuf.buf * and need to read in more until we have len+n (up to * len+max if possible) */ clear_sys_error(); if (s->rbio != NULL) { s->rwstate=SSL_READING; i=BIO_read(s->rbio, &(s->s3->rbuf.buf[off+newb]), max-newb); i=BIO_read(s->rbio,pkt+len+left, max-left); } else { Loading @@ -205,15 +232,15 @@ int ssl3_read_n(SSL *s, int n, int max, int extend) if (i <= 0) { s->s3->rbuf.left = newb; rb->left = left; return(i); } newb+=i; left+=i; } /* done reading, now the book-keeping */ s->s3->rbuf.offset = off + n; s->s3->rbuf.left = newb - n; rb->offset += n; rb->left = left - n; s->packet_length += n; s->rwstate=SSL_NOTHING; return(n); Loading Loading @@ -579,14 +606,14 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, { unsigned char *p,*plen; int i,mac_size,clear=0; int prefix_len = 0; int prefix_len=0,align=0; SSL3_RECORD *wr; SSL3_BUFFER *wb; SSL3_BUFFER *wb=&(s->s3->wbuf); SSL_SESSION *sess; /* first check if there is a SSL3_BUFFER still being written * out. This will happen with non blocking IO */ if (s->s3->wbuf.left != 0) if (wb->left != 0) return(ssl3_write_pending(s,type,buf,len)); /* If we have an alert to send, lets send it */ Loading @@ -602,7 +629,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, return 0; wr= &(s->s3->wrec); wb= &(s->s3->wbuf); sess=s->session; if ( (sess == NULL) || Loading Loading @@ -643,7 +669,32 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, s->s3->empty_fragment_done = 1; } p = wb->buf + prefix_len; if (create_empty_fragment) { #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 /* extra fragment would be couple of cipher blocks, * which would be multiple of SSL3_ALIGN_PAYLOAD, so * if we want to align the real payload, then we can * just pretent we simply have two headers. */ align = (int)wb->buf + 2*SSL3_RT_HEADER_LENGTH; align = (-align)&(SSL3_ALIGN_PAYLOAD-1); #endif p = wb->buf + align; wb->offset = align; } else if (prefix_len) { p = wb->buf + wb->offset + prefix_len; } else { #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 align = (int)wb->buf + SSL3_RT_HEADER_LENGTH; align = (-align)&(SSL3_ALIGN_PAYLOAD-1); #endif p = wb->buf + align; wb->offset = align; } /* write the header */ Loading Loading @@ -714,7 +765,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* now let's set up wb */ wb->left = prefix_len + wr->length; wb->offset = 0; /* memorize arguments so that ssl3_write_pending can detect bad write retries later */ s->s3->wpend_tot=len; Loading @@ -733,6 +783,7 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, unsigned int len) { int i; SSL3_BUFFER *wb=&(s->s3->wbuf); /* XXXX */ if ((s->s3->wpend_tot > (int)len) Loading @@ -751,24 +802,25 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, { s->rwstate=SSL_WRITING; i=BIO_write(s->wbio, (char *)&(s->s3->wbuf.buf[s->s3->wbuf.offset]), (unsigned int)s->s3->wbuf.left); (char *)&(wb->buf[wb->offset]), (unsigned int)wb->left); } else { SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BIO_NOT_SET); i= -1; } if (i == s->s3->wbuf.left) if (i == wb->left) { s->s3->wbuf.left=0; wb->left=0; wb->offset+=i; s->rwstate=SSL_NOTHING; return(s->s3->wpend_ret); } else if (i <= 0) return(i); s->s3->wbuf.offset+=i; s->s3->wbuf.left-=i; wb->offset+=i; wb->left-=i; } } Loading
ssl/ssl3.h +18 −4 Original line number Diff line number Diff line Loading @@ -248,12 +248,27 @@ extern "C" { #define SSL3_SESSION_ID_SIZE 32 #define SSL3_RT_HEADER_LENGTH 5 #ifndef SSL3_ALIGN_PAYLOAD /* Some will argue that this increases memory footprint, but it's * not actually true. Point is that malloc has to return at least * 64-bit aligned pointers, meaning that allocating 5 bytes wastes * 3 bytes in either case. Suggested pre-gaping simply moves these * wasted bytes from the end of allocated region to its front, * but makes data payload aligned, which improves performance:-) */ # define SSL3_ALIGN_PAYLOAD 8 #else # if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0 # error "insane SSL3_ALIGN_PAYLOAD" # undef SSL3_ALIGN_PAYLOAD # endif #endif /* This is the maximum MAC (digest) size used by the SSL library. * Currently this is 20 when SHA1 is used. This must be updated if larger * digests are used in future. * Currently maximum of 20 is used by SHA1, but we reserve for * future extension for 512-bit hashes. */ #define SSL3_RT_MAX_MD_SIZE 20 #define SSL3_RT_MAX_MD_SIZE 64 /* Maximum block size used in all ciphersuites. Currently 16 for AES. */ Loading Loading @@ -292,7 +307,6 @@ extern "C" { (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH) #define SSL3_RT_MAX_PACKET_SIZE \ (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) #define SSL3_RT_MAX_DATA_SIZE (1024*1024) #define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" #define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" Loading