/* read encrypted data on socket */ int readenc (Shishi * h, int sock, char *buf, int *len, char *iv, int *ivlen, Shishi_key * enckey) { char *out; char *outbis; char *iv2; int rc; int val; int outlen; int dlen = 0, blocksize, enctype, hashsize; /* read size of message */ read (sock, &dlen, sizeof (int)); dlen = ntohl (dlen); /* if 0 put read size to 0 */ if (!dlen) { *len = dlen; return SHISHI_OK; } /* convert size to encryption size */ enctype = shishi_key_type (enckey); blocksize = shishi_cipher_blocksize (enctype); hashsize = shishi_checksum_cksumlen (shishi_cipher_defaultcksumtype (enctype)); dlen += blocksize - 1 + 4; if (shishi_key_type (enckey) != SHISHI_DES3_CBC_HMAC_SHA1_KD) dlen += hashsize; else dlen += blocksize; dlen /= blocksize; dlen *= blocksize; if (shishi_key_type (enckey) == SHISHI_DES3_CBC_HMAC_SHA1_KD) dlen += hashsize; /* read encrypted data */ outbis = malloc (dlen); if (outbis == NULL) { printf ("Malloc error!\n"); return 1; } rc = read (sock, outbis, dlen); if (rc != dlen) { printf ("Error during read socket\n"); return 1; } /* decrypt it */ rc = shishi_decrypt_ivupdate (h, enckey, 1026, iv, *ivlen, &iv2, ivlen, outbis, dlen, &out, &outlen); if (rc != SHISHI_OK) { printf ("decryption error\n"); return 1; } /* len = first 4 bytes of decrypted data */ *len = ntohl (*((int *) out)); /* update iv */ memcpy (iv, iv2, *ivlen); /* Temp patch to remove 5 unidentified bytes data from server */ memset (buf, 0, BUFLEN); if ((unsigned char) out[4] == 255) val = 5 + sizeof (int); else val = sizeof (int); /* copy decrypted data to output */ memcpy (buf, out + val, strlen (out + val)); free (out); free (outbis); return SHISHI_OK; }
/* read encrypted data on socket */ int readenc (Shishi * h, int sock, char *buf, int *len, shishi_ivector * iv, Shishi_key * enckey, int proto) { char *out; char *outbis; int rc; int val; int outlen; int dlen = 0, blocksize, enctype, hashsize; /* read size of message */ read (sock, &dlen, sizeof (int)); dlen = ntohl (dlen); /* if 0 put read size to 0 */ if (!dlen) { *len = dlen; return SHISHI_OK; } if (proto == 1) *len = dlen; /* convert size to encryption size */ enctype = shishi_key_type (enckey); blocksize = shishi_cipher_blocksize (enctype); hashsize = shishi_checksum_cksumlen (shishi_cipher_defaultcksumtype (enctype)); switch (enctype) { case SHISHI_AES128_CTS_HMAC_SHA1_96: case SHISHI_AES256_CTS_HMAC_SHA1_96: dlen += 4 + hashsize + blocksize; break; case SHISHI_ARCFOUR_HMAC: case SHISHI_ARCFOUR_HMAC_EXP: dlen += 4 + 8 + blocksize - 1; dlen /= blocksize; dlen *= blocksize; dlen += hashsize; break; case SHISHI_DES3_CBC_HMAC_SHA1_KD: dlen += 4 + 2 * blocksize - 1; dlen /= blocksize; dlen *= blocksize; dlen += hashsize; break; case SHISHI_DES_CBC_CRC: dlen += 2 * blocksize - 1; if (proto == 2) dlen += 4; dlen += hashsize; dlen /= blocksize; dlen *= blocksize; break; default: dlen += blocksize - 1; if (proto == 2) dlen += 4; dlen += hashsize; dlen /= blocksize; dlen *= blocksize; break; } /* read encrypted data */ outbis = malloc (dlen); if (outbis == NULL) { perror ("readenc()"); return 1; } rc = read (sock, outbis, dlen); if (rc != dlen) { fprintf (stderr, "Error during read socket\n"); free (outbis); return 1; } if (proto == 1) { rc = shishi_decrypt (h, enckey, iv->keyusage, outbis, dlen, &out, &outlen); if (rc != SHISHI_OK) { fprintf (stderr, "decryption error\n"); free (outbis); return 1; } val = 0; } else { rc = shishi_crypto_decrypt (iv->ctx, outbis, dlen, &out, &outlen); if (rc != SHISHI_OK) { fprintf (stderr, "decryption error\n"); free (outbis); return 1; } /* in KCMDV0.2 first 4 bytes of decrypted data = len of data */ *len = ntohl (*((int *) out)); val = sizeof (int); } memset (buf, 0, BUFLEN); /* copy decrypted data to output */ memcpy (buf, out + val, outlen - val); free (out); free (outbis); return SHISHI_OK; }