enc_writ.c revision 306195
10SN/A/* crypto/des/enc_writ.c */ 20SN/A/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 30SN/A * All rights reserved. 40SN/A * 57636SN/A * This package is an SSL implementation written 67636SN/A * by Eric Young (eay@cryptsoft.com). 77636SN/A * The implementation was written so as to conform with Netscapes SSL. 87636SN/A * 97636SN/A * This library is free for commercial and non-commercial use as long as 107636SN/A * the following conditions are aheared to. The following conditions 117636SN/A * apply to all code found in this distribution, be it the RC4, RSA, 127636SN/A * lhash, DES, etc., code; not just the SSL code. The SSL documentation 130SN/A * included with this distribution is covered by the same copyright terms 147636SN/A * except that the holder is Tim Hudson (tjh@cryptsoft.com). 150SN/A * 167636SN/A * Copyright remains Eric Young's, and as such any Copyright notices in 177636SN/A * the code are not to be removed. 187636SN/A * If this package is used in a product, Eric Young should be given attribution 197636SN/A * as the author of the parts of the library used. 207636SN/A * This can be in the form of a textual message at program startup or 217636SN/A * in documentation (online or textual) provided with the package. 220SN/A * 230SN/A * Redistribution and use in source and binary forms, with or without 240SN/A * modification, are permitted provided that the following conditions 250SN/A * are met: 260SN/A * 1. Redistributions of source code must retain the copyright 270SN/A * notice, this list of conditions and the following disclaimer. 280SN/A * 2. Redistributions in binary form must reproduce the above copyright 290SN/A * notice, this list of conditions and the following disclaimer in the 300SN/A * documentation and/or other materials provided with the distribution. 310SN/A * 3. All advertising materials mentioning features or use of this software 320SN/A * must display the following acknowledgement: 330SN/A * "This product includes cryptographic software written by 340SN/A * Eric Young (eay@cryptsoft.com)" 350SN/A * The word 'cryptographic' can be left out if the rouines from the library 360SN/A * being used are not cryptographic related :-). 370SN/A * 4. If you include any Windows specific code (or a derivative thereof) from 380SN/A * the apps directory (application code) you must include an acknowledgement: 390SN/A * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 400SN/A * 410SN/A * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 420SN/A * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 430SN/A * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 440SN/A * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 450SN/A * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 460SN/A * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 470SN/A * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 480SN/A * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 490SN/A * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 500SN/A * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 517475SN/A * SUCH DAMAGE. 520SN/A * 530SN/A * The licence and distribution terms for any publically available version or 540SN/A * derivative of this code cannot be changed. i.e. this code cannot simply be 557475SN/A * copied and put under another distribution licence 560SN/A * [including the GNU Public Licence.] 570SN/A */ 580SN/A 590SN/A#include <errno.h> 600SN/A#include <time.h> 610SN/A#include <stdio.h> 620SN/A#include "cryptlib.h" 630SN/A#include "des_locl.h" 640SN/A#include <openssl/rand.h> 657636SN/A 660SN/A/*- 670SN/A * WARNINGS: 680SN/A * 690SN/A * - The data format used by DES_enc_write() and DES_enc_read() 700SN/A * has a cryptographic weakness: When asked to write more 710SN/A * than MAXWRITE bytes, DES_enc_write will split the data 720SN/A * into several chunks that are all encrypted 730SN/A * using the same IV. So don't use these functions unless you 740SN/A * are sure you know what you do (in which case you might 750SN/A * not want to use them anyway). 760SN/A * 770SN/A * - This code cannot handle non-blocking sockets. 780SN/A */ 790SN/A 807636SN/Aint DES_enc_write(int fd, const void *_buf, int len, 817636SN/A DES_key_schedule *sched, DES_cblock *iv) 827636SN/A{ 837636SN/A#if defined(OPENSSL_NO_POSIX_IO) 847636SN/A return (-1); 857636SN/A#else 867636SN/A# ifdef _LIBC 877636SN/A extern unsigned long time(); 889883SN/A extern int write(); 899883SN/A# endif 909883SN/A const unsigned char *buf = _buf; 919883SN/A long rnum; 927636SN/A int i, j, k, outnum; 937636SN/A static unsigned char *outbuf = NULL; 947636SN/A unsigned char shortbuf[8]; 957636SN/A unsigned char *p; 967636SN/A const unsigned char *cp; 977636SN/A static int start = 1; 987636SN/A 997636SN/A if (len < 0) 1007636SN/A return -1; 1017636SN/A 1027636SN/A if (outbuf == NULL) { 1037636SN/A outbuf = OPENSSL_malloc(BSIZE + HDRSIZE); 1047636SN/A if (outbuf == NULL) 1057636SN/A return (-1); 1067636SN/A } 1077636SN/A /* 1087636SN/A * If we are sending less than 8 bytes, the same char will look the same 1097636SN/A * if we don't pad it out with random bytes 1107636SN/A */ 1117636SN/A if (start) { 1127636SN/A start = 0; 1137636SN/A } 1147636SN/A 1157636SN/A /* lets recurse if we want to send the data in small chunks */ 1167636SN/A if (len > MAXWRITE) { 1177636SN/A j = 0; 1187636SN/A for (i = 0; i < len; i += k) { 1197636SN/A k = DES_enc_write(fd, &(buf[i]), 1207636SN/A ((len - i) > MAXWRITE) ? MAXWRITE : (len - i), 1217636SN/A sched, iv); 1227636SN/A if (k < 0) 1237636SN/A return (k); 1247636SN/A else 1257636SN/A j += k; 1267636SN/A } 1277636SN/A return (j); 1287636SN/A } 1297636SN/A 1307636SN/A /* write length first */ 1317636SN/A p = outbuf; 1327636SN/A l2n(len, p); 1337636SN/A 1347636SN/A /* pad short strings */ 1357636SN/A if (len < 8) { 1367636SN/A cp = shortbuf; 1377636SN/A memcpy(shortbuf, buf, len); 1387636SN/A if (RAND_bytes(shortbuf + len, 8 - len) <= 0) { 1397636SN/A return -1; 1407636SN/A } 1417636SN/A rnum = 8; 1427636SN/A } else { 1437636SN/A cp = buf; 1447636SN/A rnum = ((len + 7) / 8 * 8); /* round up to nearest eight */ 1457636SN/A } 1467636SN/A 1477636SN/A if (DES_rw_mode & DES_PCBC_MODE) 1487636SN/A DES_pcbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched, 1497636SN/A iv, DES_ENCRYPT); 1507636SN/A else 1517636SN/A DES_cbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched, 1527636SN/A iv, DES_ENCRYPT); 1537636SN/A 1547636SN/A /* output */ 1557636SN/A outnum = rnum + HDRSIZE; 1567636SN/A 1577636SN/A for (j = 0; j < outnum; j += i) { 1580SN/A /* 1590SN/A * eay 26/08/92 I was not doing writing from where we got up to. 1607636SN/A */ 1617636SN/A# ifndef _WIN32 1627636SN/A i = write(fd, (void *)&(outbuf[j]), outnum - j); 1637636SN/A# else 1647636SN/A i = _write(fd, (void *)&(outbuf[j]), outnum - j); 1650SN/A# endif 1667636SN/A if (i == -1) { 1677636SN/A# ifdef EINTR 1687636SN/A if (errno == EINTR) 1697636SN/A i = 0; 1707636SN/A else 1717636SN/A# endif 1727636SN/A /* 1737636SN/A * This is really a bad error - very bad It will stuff-up 1740SN/A * both ends. 1757636SN/A */ 1767636SN/A return (-1); 1777636SN/A } 1780SN/A } 1797636SN/A 1807636SN/A return (len); 1817636SN/A#endif /* OPENSSL_NO_POSIX_IO */ 1827636SN/A} 1837636SN/A