/* The DTLS Generate Cookie callback * return : number of bytes copied into buf, or error */ int EmbedGenerateCookie(CYASSL* ssl, byte *buf, int sz, void *ctx) { int sd = ssl->wfd; struct sockaddr_storage peer; XSOCKLENT peerSz = sizeof(peer); Sha sha; byte digest[SHA_DIGEST_SIZE]; int ret = 0; (void)ctx; XMEMSET(&peer, 0, sizeof(peer)); if (getpeername(sd, (struct sockaddr*)&peer, &peerSz) != 0) { CYASSL_MSG("getpeername failed in EmbedGenerateCookie"); return GEN_COOKIE_E; } ret = InitSha(&sha); if (ret != 0) return ret; ShaUpdate(&sha, (byte*)&peer, peerSz); ShaFinal(&sha, digest); if (sz > SHA_DIGEST_SIZE) sz = SHA_DIGEST_SIZE; XMEMCPY(buf, digest, sz); return sz; }
void bench_sha(void) { Sha hash; byte digest[SHA_DIGEST_SIZE]; double start, total, persec; int i, ret; ret = InitSha(&hash); if (ret != 0) { printf("InitSha failed, ret = %d\n", ret); return; } start = current_time(1); for(i = 0; i < numBlocks; i++) ShaUpdate(&hash, plain, sizeof(plain)); ShaFinal(&hash, digest); total = current_time(0) - start; persec = 1 / total * numBlocks; #ifdef BENCH_EMBEDDED /* since using kB, convert to MB/s */ persec = persec / 1024; #endif printf("SHA %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks, blockType, total, persec); }
/* The DTLS Generate Cookie callback * return : number of bytes copied into buf, or error */ int EmbedGenerateCookie(byte *buf, int sz, void *ctx) { CYASSL* ssl = (CYASSL*)ctx; int sd = ssl->wfd; struct sockaddr_storage peer; socklen_t peerSz = sizeof(peer); byte cookieSrc[sizeof(struct in6_addr) + sizeof(int)]; int cookieSrcSz = 0; Sha sha; getpeername(sd, (struct sockaddr*)&peer, &peerSz); if (peer.ss_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in*)&peer; cookieSrcSz = sizeof(struct in_addr) + sizeof(s->sin_port); XMEMCPY(cookieSrc, &s->sin_port, sizeof(s->sin_port)); XMEMCPY(cookieSrc + sizeof(s->sin_port), &s->sin_addr, sizeof(struct in_addr)); } else if (peer.ss_family == AF_INET6) { struct sockaddr_in6 *s = (struct sockaddr_in6*)&peer; cookieSrcSz = sizeof(struct in6_addr) + sizeof(s->sin6_port); XMEMCPY(cookieSrc, &s->sin6_port, sizeof(s->sin6_port)); XMEMCPY(cookieSrc + sizeof(s->sin6_port), &s->sin6_addr, sizeof(struct in6_addr)); } InitSha(&sha); ShaUpdate(&sha, cookieSrc, cookieSrcSz); ShaFinal(&sha, buf); return SHA_DIGEST_SIZE; }
int ShaHash(const byte* data, word32 len, byte* hash) { int ret = 0; #ifdef CYASSL_SMALL_STACK Sha* sha; #else Sha sha[1]; #endif #ifdef CYASSL_SMALL_STACK sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER); if (sha == NULL) return MEMORY_E; #endif if ((ret = InitSha(sha)) != 0) { CYASSL_MSG("InitSha failed"); } else { ShaUpdate(sha, data, len); ShaFinal(sha, hash); } #ifdef CYASSL_SMALL_STACK XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; }
void ShaFinal(Sha* sha, byte* hash) { __IO uint16_t nbvalidbitsdata = 0; /* finish reading any trailing bytes into FIFO */ if (sha->buffLen) { HASH_DataIn(*(uint32_t*)sha->buffer); sha->loLen += sha->buffLen; } /* calculate number of valid bits in last word of input data */ nbvalidbitsdata = 8 * (sha->loLen % SHA_REG_SIZE); /* configure number of valid bits in last word of the data */ HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); /* start HASH processor */ HASH_StartDigest(); /* wait until Busy flag == RESET */ while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {} /* read message digest */ sha->digest[0] = HASH->HR[0]; sha->digest[1] = HASH->HR[1]; sha->digest[2] = HASH->HR[2]; sha->digest[3] = HASH->HR[3]; sha->digest[4] = HASH->HR[4]; ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE); XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE); InitSha(sha); /* reset state */ }
/* check mcapi sha against internal */ static int check_sha(void) { CRYPT_SHA_CTX mcSha; Sha defSha; int ret = 0; byte mcDigest[CRYPT_SHA_DIGEST_SIZE]; byte defDigest[SHA_DIGEST_SIZE]; CRYPT_SHA_Initialize(&mcSha); ret = InitSha(&defSha); if (ret != 0) { printf("sha init default failed\n"); return -1; } CRYPT_SHA_DataAdd(&mcSha, ourData, OUR_DATA_SIZE); ShaUpdate(&defSha, ourData, OUR_DATA_SIZE); CRYPT_SHA_Finalize(&mcSha, mcDigest); ShaFinal(&defSha, defDigest); if (memcmp(mcDigest, defDigest, CRYPT_SHA_DIGEST_SIZE) != 0) { printf("sha final memcmp failed\n"); return -1; } printf("sha mcapi test passed\n"); return 0; }
int sha_test(void) { Sha sha; byte hash[SHA_DIGEST_SIZE]; testVector a, b, c, d; testVector test_sha[4]; int ret = 0; int times = sizeof(test_sha) / sizeof(struct testVector), i; a.input = "abc"; a.output = "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2" "\x6C\x9C\xD0\xD8\x9D"; a.inLen = strlen(a.input); a.outLen = strlen(a.output); b.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; b.output = "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29" "\xE5\xE5\x46\x70\xF1"; b.inLen = strlen(b.input); b.outLen = strlen(b.output); c.input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaa"; c.output = "\x00\x98\xBA\x82\x4B\x5C\x16\x42\x7B\xD7\xA1\x12\x2A\x5A\x44" "\x2A\x25\xEC\x64\x4D"; c.inLen = strlen(c.input); c.outLen = strlen(c.output); d.input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaa"; d.output = "\xAD\x5B\x3F\xDB\xCB\x52\x67\x78\xC2\x83\x9D\x2F\x15\x1E\xA7" "\x53\x99\x5E\x26\xA0"; d.inLen = strlen(d.input); d.outLen = strlen(d.output); test_sha[0] = a; test_sha[1] = b; test_sha[2] = c; test_sha[3] = d; ret = InitSha(&sha); if (ret != 0) return ret; for (i = 0; i < times; ++i) { ShaUpdate(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen); ShaFinal(&sha, hash); if (memcmp(hash, test_sha[i].output, SHA_DIGEST_SIZE) != 0) return -10 - i; } return 0; }
/* Initialize SHA */ int CRYPT_SHA_Initialize(CRYPT_SHA_CTX* sha) { typedef char sha_test[sizeof(CRYPT_SHA_CTX) >= sizeof(Sha) ? 1 : -1]; (void)sizeof(sha_test); if (sha == NULL) return BAD_FUNC_ARG; return InitSha((Sha*)sha); }
tr_sha1_ctx_t tr_sha1_init (void) { Sha * handle = tr_new (Sha, 1); if (check_result (InitSha (handle))) return handle; tr_free (handle); return NULL; }
static int InitHmac(Hmac* hmac, int type) { int ret = 0; hmac->innerHashKeyed = 0; hmac->macType = (byte)type; if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384 || type == SHA512 || type == BLAKE2B_ID)) return BAD_FUNC_ARG; switch (type) { #ifndef NO_MD5 case MD5: InitMd5(&hmac->hash.md5); break; #endif #ifndef NO_SHA case SHA: ret = InitSha(&hmac->hash.sha); break; #endif #ifndef NO_SHA256 case SHA256: ret = InitSha256(&hmac->hash.sha256); break; #endif #ifdef CYASSL_SHA384 case SHA384: ret = InitSha384(&hmac->hash.sha384); break; #endif #ifdef CYASSL_SHA512 case SHA512: ret = InitSha512(&hmac->hash.sha512); break; #endif #ifdef HAVE_BLAKE2 case BLAKE2B_ID: ret = InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256); break; #endif default: return BAD_FUNC_ARG; } return ret; }
/* Create and store the master secret see page 32, 6.1 */ int MakeMasterSecret(SSL* ssl) { byte shaOutput[SHA_DIGEST_SIZE]; byte md5Input[ENCRYPT_LEN + SHA_DIGEST_SIZE]; byte shaInput[PREFIX + ENCRYPT_LEN + 2 * RAN_LEN]; int i; word32 idx; word32 pmsSz = ssl->arrays.preMasterSz; Md5 md5; Sha sha; #ifndef NO_TLS if (ssl->options.tls) return MakeTlsMasterSecret(ssl); #endif InitMd5(&md5); InitSha(&sha); memcpy(md5Input, ssl->arrays.preMasterSecret, pmsSz); for (i = 0; i < MASTER_ROUNDS; ++i) { byte prefix[PREFIX]; if (!SetPrefix(prefix, i)) { return PREFIX_ERROR; } idx = 0; memcpy(shaInput, prefix, i + 1); idx += i + 1; memcpy(shaInput + idx, ssl->arrays.preMasterSecret, pmsSz); idx += pmsSz; memcpy(shaInput + idx, ssl->arrays.clientRandom, RAN_LEN); idx += RAN_LEN; memcpy(shaInput + idx, ssl->arrays.serverRandom, RAN_LEN); idx += RAN_LEN; ShaUpdate(&sha, shaInput, idx); ShaFinal(&sha, shaOutput); idx = pmsSz; /* preSz */ memcpy(md5Input + idx, shaOutput, SHA_DIGEST_SIZE); idx += SHA_DIGEST_SIZE; Md5Update(&md5, md5Input, idx); Md5Final(&md5, &ssl->arrays.masterSecret[i * MD5_DIGEST_SIZE]); } DeriveKeys(ssl); CleanPreMaster(ssl); return 0; }
int ShaFinal(Sha* sha, byte* hash) { byte* local = (byte*)sha->buffer; AddLength(sha, sha->buffLen); /* before adding pads */ local[sha->buffLen++] = 0x80; /* add 1 */ /* pad with zeros */ if (sha->buffLen > SHA_PAD_SIZE) { XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen); sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen; #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE); #endif XTRANSFORM(sha, local); sha->buffLen = 0; } XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen); /* put lengths in bits */ sha->hiLen = (sha->loLen >> (8*sizeof(sha->loLen) - 3)) + (sha->hiLen << 3); sha->loLen = sha->loLen << 3; /* store lengths */ #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE); #endif /* ! length ordering dependent on digest endian type ! */ XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32)); XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32)); #ifdef FREESCALE_MMCAU /* Kinetis requires only these bytes reversed */ ByteReverseWords(&sha->buffer[SHA_PAD_SIZE/sizeof(word32)], &sha->buffer[SHA_PAD_SIZE/sizeof(word32)], 2 * sizeof(word32)); #endif XTRANSFORM(sha, local); #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE); #endif XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE); return InitSha(sha); /* reset state */ }
int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, int sLen, int iterations, int kLen, int hashType) { Md5 md5; Sha sha; int hLen = (hashType == MD5) ? (int)MD5_DIGEST_SIZE : (int)SHA_DIGEST_SIZE; int i, ret = 0; byte buffer[SHA_DIGEST_SIZE]; /* max size */ if (hashType != MD5 && hashType != SHA) return BAD_FUNC_ARG; if (kLen > hLen) return BAD_FUNC_ARG; if (iterations < 1) return BAD_FUNC_ARG; if (hashType == MD5) { InitMd5(&md5); Md5Update(&md5, passwd, pLen); Md5Update(&md5, salt, sLen); Md5Final(&md5, buffer); } else { ret = InitSha(&sha); if (ret != 0) return ret; ShaUpdate(&sha, passwd, pLen); ShaUpdate(&sha, salt, sLen); ShaFinal(&sha, buffer); } for (i = 1; i < iterations; i++) { if (hashType == MD5) { Md5Update(&md5, buffer, hLen); Md5Final(&md5, buffer); } else { ShaUpdate(&sha, buffer, hLen); ShaFinal(&sha, buffer); } } XMEMCPY(output, buffer, kLen); return 0; }
int DeriveKeys(SSL* ssl) { int length = 2 * ssl->specs.hash_size + 2 * ssl->specs.key_size + 2 * ssl->specs.iv_size; int rounds = (length + MD5_DIGEST_SIZE - 1 ) / MD5_DIGEST_SIZE, i; byte shaOutput[SHA_DIGEST_SIZE]; byte md5Input[SECRET_LEN + SHA_DIGEST_SIZE]; byte shaInput[KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN]; Md5 md5; Sha sha; byte keyData[KEY_PREFIX * MD5_DIGEST_SIZE]; /* max size */ InitMd5(&md5); InitSha(&sha); XMEMCPY(md5Input, ssl->arrays.masterSecret, SECRET_LEN); for (i = 0; i < rounds; ++i) { int j = i + 1; int idx = j; if (!SetPrefix(shaInput, i)) { return PREFIX_ERROR; } XMEMCPY(shaInput + idx, ssl->arrays.masterSecret, SECRET_LEN); idx += SECRET_LEN; XMEMCPY(shaInput + idx, ssl->arrays.serverRandom, RAN_LEN); idx += RAN_LEN; XMEMCPY(shaInput + idx, ssl->arrays.clientRandom, RAN_LEN); idx += RAN_LEN; ShaUpdate(&sha, shaInput, sizeof(shaInput) - KEY_PREFIX + j); ShaFinal(&sha, shaOutput); XMEMCPY(&md5Input[SECRET_LEN], shaOutput, SHA_DIGEST_SIZE); Md5Update(&md5, md5Input, sizeof(md5Input)); Md5Final(&md5, keyData + i * MD5_DIGEST_SIZE); } return StoreKeys(ssl, keyData); }
static int InitHmac(Hmac* hmac, int type) { hmac->innerHashKeyed = 0; hmac->macType = (byte)type; if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384 || type == SHA512)) return BAD_FUNC_ARG; switch (type) { #ifndef NO_MD5 case MD5: InitMd5(&hmac->hash.md5); break; #endif #ifndef NO_SHA case SHA: InitSha(&hmac->hash.sha); break; #endif #ifndef NO_SHA256 case SHA256: InitSha256(&hmac->hash.sha256); break; #endif #ifdef CYASSL_SHA384 case SHA384: InitSha384(&hmac->hash.sha384); break; #endif #ifdef CYASSL_SHA512 case SHA512: InitSha512(&hmac->hash.sha512); break; #endif default: break; } return 0; }
static int InitHmac(Hmac* hmac, int type) { hmac->innerHashKeyed = 0; hmac->macType = (byte)type; if (!(type == MD5 || type == SHA || type == SHA256)) return BAD_FUNC_ARG; if (type == MD5) InitMd5(&hmac->hash.md5); else if (type == SHA) InitSha(&hmac->hash.sha); #ifndef NO_SHA256 else if (type == SHA256) InitSha256(&hmac->hash.sha256); #endif return 0; }
void ShaFinal(Sha* sha, byte* hash) { byte* local = (byte*)sha->buffer; AddLength(sha, sha->buffLen); /* before adding pads */ local[sha->buffLen++] = 0x80; /* add 1 */ /* pad with zeros */ if (sha->buffLen > SHA_PAD_SIZE) { XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen); sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen; #ifdef LITTLE_ENDIAN_ORDER ByteReverseBytes(local, local, SHA_BLOCK_SIZE); #endif Transform(sha); sha->buffLen = 0; } XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen); /* put lengths in bits */ sha->hiLen = (sha->loLen >> (8*sizeof(sha->loLen) - 3)) + (sha->hiLen << 3); sha->loLen = sha->loLen << 3; /* store lengths */ #ifdef LITTLE_ENDIAN_ORDER ByteReverseBytes(local, local, SHA_BLOCK_SIZE); #endif /* ! length ordering dependent on digest endian type ! */ XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32)); XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32)); Transform(sha); #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE); #endif XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE); InitSha(sha); /* reset state */ }
int dsa_test() { int ret, answer; word32 bytes; word32 idx = 0; byte tmp[1024]; DsaKey key; RNG rng; FILE* file = fopen(dsaKey, "rb"); Sha sha; byte hash[SHA_DIGEST_SIZE]; byte signature[40]; if (!file) return -60; bytes = (word32) fread(tmp, 1, sizeof(tmp), file); InitSha(&sha); ShaUpdate(&sha, tmp, bytes); ShaFinal(&sha, hash); InitDsaKey(&key); ret = DsaPrivateKeyDecode(tmp, &idx, &key, bytes); if (ret != 0) return -61; ret = InitRng(&rng); if (ret != 0) return -62; ret = DsaSign(hash, signature, &key, &rng); if (ret != 0) return -63; ret = DsaVerify(hash, signature, &key, &answer); if (ret != 0) return -64; if (answer != 1) return -65; FreeDsaKey(&key); fclose(file); return 0; }
void bench_sha(void) { Sha hash; byte digest[SHA_DIGEST_SIZE]; double start, total, persec; int i; InitSha(&hash); start = current_time(); for(i = 0; i < megs; i++) ShaUpdate(&hash, plain, sizeof(plain)); ShaFinal(&hash, digest); total = current_time() - start; persec = 1 / total * megs; printf("SHA %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, persec); }
/* The DTLS Generate Cookie callback * return : number of bytes copied into buf, or error */ int EmbedGenerateCookie(CYASSL* ssl, byte *buf, int sz, void *ctx) { int sd = ssl->wfd; struct sockaddr_in peer; XSOCKLENT peerSz = sizeof(peer); byte cookieSrc[sizeof(struct in_addr) + sizeof(int)]; int cookieSrcSz = 0; Sha sha; (void)ctx; if (getpeername(sd, (struct sockaddr*)&peer, &peerSz) != 0) { CYASSL_MSG("getpeername failed in EmbedGenerateCookie"); return GEN_COOKIE_E; } if (peer.sin_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in*)&peer; cookieSrcSz = sizeof(struct in_addr) + sizeof(s->sin_port); XMEMCPY(cookieSrc, &s->sin_port, sizeof(s->sin_port)); XMEMCPY(cookieSrc + sizeof(s->sin_port), &s->sin_addr, sizeof(struct in_addr)); } InitSha(&sha); ShaUpdate(&sha, cookieSrc, cookieSrcSz); if (sz < SHA_DIGEST_SIZE) { byte digest[SHA_DIGEST_SIZE]; ShaFinal(&sha, digest); XMEMCPY(buf, digest, sz); return sz; } ShaFinal(&sha, buf); return SHA_DIGEST_SIZE; }
/* * k5_sha1_hash: Hash data buffer using SHA1. * * @data Input data structure * @num_data Number of blocks * @output Output data structure * * Returns 0 on success, krb5_error_code on error */ static krb5_error_code k5_sha1_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { Sha sha; unsigned int i; if (output->length != SHA_DIGEST_SIZE) return(KRB5_CRYPTO_INTERNAL); InitSha(&sha); for (i = 0; i < num_data; i++) { const krb5_crypto_iov *iov = &data[i]; if (SIGN_IOV(iov)) { ShaUpdate(&sha, (unsigned char *) iov->data.data, iov->data.length); } } ShaFinal(&sha, (unsigned char *) output->data); return(0); }
/* The DTLS Generate Cookie callback * return : number of bytes copied into buf, or error */ int EmbedGenerateCookie(CYASSL* ssl, byte *buf, int sz, void *ctx) { int sd = ssl->wfd; struct sockaddr_in6 peer; XSOCKLENT peerSz = sizeof(peer); Sha sha; byte digest[SHA_DIGEST_SIZE]; (void)ctx; if (getpeername(sd, (struct sockaddr*)&peer, &peerSz) != 0) { CYASSL_MSG("getpeername failed in EmbedGenerateCookie"); return GEN_COOKIE_E; } InitSha(&sha); if (peer.sin6_family == AF_INET6) { ShaUpdate(&sha, (byte*)&peer.sin6_port, sizeof(peer.sin6_port)); ShaUpdate(&sha, (byte*)&peer.sin6_addr, sizeof(peer.sin6_addr)); } else if (peer.sin6_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in*)&peer; ShaUpdate(&sha, (byte*)&s->sin_port, sizeof(s->sin_port)); ShaUpdate(&sha, (byte*)&s->sin_addr, sizeof(s->sin_addr)); } else { CYASSL_MSG("peer sin_family unknown type in EmbedGenerateCookie"); return GEN_COOKIE_E; } ShaFinal(&sha, digest); if (sz > SHA_DIGEST_SIZE) sz = SHA_DIGEST_SIZE; XMEMCPY(buf, digest, sz); return sz; }
static int capwap_crypt_createcookie(CYASSL* ssl, unsigned char* buffer, int size, void* context) { int length; unsigned char temp[32]; Sha sha; byte digest[SHA_DIGEST_SIZE]; struct capwap_dtls* dtls = (struct capwap_dtls*)context; if (size != SHA_DIGEST_SIZE) { return -1; } /* Create buffer with peer's address and port */ if (dtls->peeraddr.ss.ss_family == AF_INET) { length = sizeof(struct in_addr) + sizeof(in_port_t); memcpy(temp, &dtls->peeraddr.sin.sin_port, sizeof(in_port_t)); memcpy(temp + sizeof(in_port_t), &dtls->peeraddr.sin.sin_addr, sizeof(struct in_addr)); } else if (dtls->peeraddr.ss.ss_family == AF_INET6) { length = sizeof(struct in6_addr) + sizeof(in_port_t); memcpy(temp, &dtls->peeraddr.sin6.sin6_port, sizeof(in_port_t)); memcpy(temp + sizeof(in_port_t), &dtls->peeraddr.sin6.sin6_addr, sizeof(struct in6_addr)); } else { return -1; } /* */ if (InitSha(&sha)) { return -1; } ShaUpdate(&sha, temp, length); ShaFinal(&sha, digest); /* */ memcpy(buffer, digest, SHA_DIGEST_SIZE); return SHA_DIGEST_SIZE; }
int SHA1_Init(SHA_CTX *sha) { InitSha(sha); return 1; }
/* Create and store the master secret see page 32, 6.1 */ int MakeMasterSecret(SSL* ssl) { byte shaOutput[SHA_DIGEST_SIZE]; byte md5Input[ENCRYPT_LEN + SHA_DIGEST_SIZE]; byte shaInput[PREFIX + ENCRYPT_LEN + 2 * RAN_LEN]; int i, ret; word32 idx; word32 pmsSz = ssl->arrays.preMasterSz; Md5 md5; Sha sha; #ifdef SHOW_SECRETS { int j; printf("pre master secret: "); for (j = 0; j < pmsSz; j++) printf("%02x", ssl->arrays.preMasterSecret[j]); printf("\n"); } #endif #ifndef NO_TLS if (ssl->options.tls) return MakeTlsMasterSecret(ssl); #endif InitMd5(&md5); InitSha(&sha); XMEMCPY(md5Input, ssl->arrays.preMasterSecret, pmsSz); for (i = 0; i < MASTER_ROUNDS; ++i) { byte prefix[PREFIX]; if (!SetPrefix(prefix, i)) { return PREFIX_ERROR; } idx = 0; XMEMCPY(shaInput, prefix, i + 1); idx += i + 1; XMEMCPY(shaInput + idx, ssl->arrays.preMasterSecret, pmsSz); idx += pmsSz; XMEMCPY(shaInput + idx, ssl->arrays.clientRandom, RAN_LEN); idx += RAN_LEN; XMEMCPY(shaInput + idx, ssl->arrays.serverRandom, RAN_LEN); idx += RAN_LEN; ShaUpdate(&sha, shaInput, idx); ShaFinal(&sha, shaOutput); idx = pmsSz; /* preSz */ XMEMCPY(md5Input + idx, shaOutput, SHA_DIGEST_SIZE); idx += SHA_DIGEST_SIZE; Md5Update(&md5, md5Input, idx); Md5Final(&md5, &ssl->arrays.masterSecret[i * MD5_DIGEST_SIZE]); } #ifdef SHOW_SECRETS { int i; printf("master secret: "); for (i = 0; i < SECRET_LEN; i++) printf("%02x", ssl->arrays.masterSecret[i]); printf("\n"); } #endif ret = DeriveKeys(ssl); CleanPreMaster(ssl); return ret; }
/* build PKCS#7 signedData content type */ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) { static const byte outerOid[] = { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 }; static const byte innerOid[] = { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 }; ESD esd; word32 signerInfoSz = 0; word32 totalSz = 0; int idx = 0, ret = 0; byte* flatSignedAttribs = NULL; word32 flatSignedAttribsSz = 0; word32 innerOidSz = sizeof(innerOid); word32 outerOidSz = sizeof(outerOid); if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 || pkcs7->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 || pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0 || pkcs7->privateKey == NULL || pkcs7->privateKeySz == 0 || output == NULL || outputSz == 0) return BAD_FUNC_ARG; XMEMSET(&esd, 0, sizeof(esd)); ret = InitSha(&esd.sha); if (ret != 0) return ret; if (pkcs7->contentSz != 0) { ShaUpdate(&esd.sha, pkcs7->content, pkcs7->contentSz); esd.contentDigest[0] = ASN_OCTET_STRING; esd.contentDigest[1] = SHA_DIGEST_SIZE; ShaFinal(&esd.sha, &esd.contentDigest[2]); } esd.innerOctetsSz = SetOctetString(pkcs7->contentSz, esd.innerOctets); esd.innerContSeqSz = SetExplicit(0, esd.innerOctetsSz + pkcs7->contentSz, esd.innerContSeq); esd.contentInfoSeqSz = SetSequence(pkcs7->contentSz + esd.innerOctetsSz + innerOidSz + esd.innerContSeqSz, esd.contentInfoSeq); esd.issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz, esd.issuerSn); signerInfoSz += esd.issuerSnSz; esd.issuerNameSz = SetSequence(pkcs7->issuerSz, esd.issuerName); signerInfoSz += esd.issuerNameSz + pkcs7->issuerSz; esd.issuerSnSeqSz = SetSequence(signerInfoSz, esd.issuerSnSeq); signerInfoSz += esd.issuerSnSeqSz; esd.signerVersionSz = SetMyVersion(1, esd.signerVersion, 0); signerInfoSz += esd.signerVersionSz; esd.signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd.signerDigAlgoId, hashType, 0); signerInfoSz += esd.signerDigAlgoIdSz; esd.digEncAlgoIdSz = SetAlgoID(pkcs7->encryptOID, esd.digEncAlgoId, keyType, 0); signerInfoSz += esd.digEncAlgoIdSz; if (pkcs7->signedAttribsSz != 0) { byte contentTypeOid[] = { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01, 0x09, 0x03 }; byte contentType[] = { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01 }; byte messageDigestOid[] = { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04 }; PKCS7Attrib cannedAttribs[2] = { { contentTypeOid, sizeof(contentTypeOid), contentType, sizeof(contentType) }, { messageDigestOid, sizeof(messageDigestOid), esd.contentDigest, sizeof(esd.contentDigest) } }; word32 cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib); esd.signedAttribsCount += cannedAttribsCount; esd.signedAttribsSz += EncodeAttributes(&esd.signedAttribs[0], 2, cannedAttribs, cannedAttribsCount); esd.signedAttribsCount += pkcs7->signedAttribsSz; esd.signedAttribsSz += EncodeAttributes(&esd.signedAttribs[2], 4, pkcs7->signedAttribs, pkcs7->signedAttribsSz); flatSignedAttribs = (byte*)XMALLOC(esd.signedAttribsSz, 0, NULL); flatSignedAttribsSz = esd.signedAttribsSz; if (flatSignedAttribs == NULL) return MEMORY_E; FlattenAttributes(flatSignedAttribs, esd.signedAttribs, esd.signedAttribsCount); esd.signedAttribSetSz = SetImplicit(ASN_SET, 0, esd.signedAttribsSz, esd.signedAttribSet); } /* Calculate the final hash and encrypt it. */ { RsaKey privKey; int result; word32 scratch = 0; byte digestInfo[MAX_SEQ_SZ + MAX_ALGO_SZ + MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE]; byte digestInfoSeq[MAX_SEQ_SZ]; byte digestStr[MAX_OCTET_STR_SZ]; word32 digestInfoSeqSz, digestStrSz; int digIdx = 0; if (pkcs7->signedAttribsSz != 0) { byte attribSet[MAX_SET_SZ]; word32 attribSetSz; attribSetSz = SetSet(flatSignedAttribsSz, attribSet); ret = InitSha(&esd.sha); if (ret < 0) { XFREE(flatSignedAttribs, 0, NULL); return ret; } ShaUpdate(&esd.sha, attribSet, attribSetSz); ShaUpdate(&esd.sha, flatSignedAttribs, flatSignedAttribsSz); } ShaFinal(&esd.sha, esd.contentAttribsDigest); digestStrSz = SetOctetString(SHA_DIGEST_SIZE, digestStr); digestInfoSeqSz = SetSequence(esd.signerDigAlgoIdSz + digestStrSz + SHA_DIGEST_SIZE, digestInfoSeq); XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz); digIdx += digestInfoSeqSz; XMEMCPY(digestInfo + digIdx, esd.signerDigAlgoId, esd.signerDigAlgoIdSz); digIdx += esd.signerDigAlgoIdSz; XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz); digIdx += digestStrSz; XMEMCPY(digestInfo + digIdx, esd.contentAttribsDigest, SHA_DIGEST_SIZE); digIdx += SHA_DIGEST_SIZE; result = InitRsaKey(&privKey, NULL); if (result == 0) result = RsaPrivateKeyDecode(pkcs7->privateKey, &scratch, &privKey, pkcs7->privateKeySz); if (result < 0) { XFREE(flatSignedAttribs, 0, NULL); return PUBLIC_KEY_E; } result = RsaSSL_Sign(digestInfo, digIdx, esd.encContentDigest, sizeof(esd.encContentDigest), &privKey, pkcs7->rng); FreeRsaKey(&privKey); if (result < 0) { XFREE(flatSignedAttribs, 0, NULL); return result; } esd.encContentDigestSz = (word32)result; } signerInfoSz += flatSignedAttribsSz + esd.signedAttribSetSz; esd.signerDigestSz = SetOctetString(esd.encContentDigestSz, esd.signerDigest); signerInfoSz += esd.signerDigestSz + esd.encContentDigestSz; esd.signerInfoSeqSz = SetSequence(signerInfoSz, esd.signerInfoSeq); signerInfoSz += esd.signerInfoSeqSz; esd.signerInfoSetSz = SetSet(signerInfoSz, esd.signerInfoSet); signerInfoSz += esd.signerInfoSetSz; esd.certsSetSz = SetImplicit(ASN_SET, 0, pkcs7->singleCertSz, esd.certsSet); esd.singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd.singleDigAlgoId, hashType, 0); esd.digAlgoIdSetSz = SetSet(esd.singleDigAlgoIdSz, esd.digAlgoIdSet); esd.versionSz = SetMyVersion(1, esd.version, 0); totalSz = esd.versionSz + esd.singleDigAlgoIdSz + esd.digAlgoIdSetSz + esd.contentInfoSeqSz + esd.certsSetSz + pkcs7->singleCertSz + esd.innerOctetsSz + esd.innerContSeqSz + innerOidSz + pkcs7->contentSz + signerInfoSz; esd.innerSeqSz = SetSequence(totalSz, esd.innerSeq); totalSz += esd.innerSeqSz; esd.outerContentSz = SetExplicit(0, totalSz, esd.outerContent); totalSz += esd.outerContentSz + outerOidSz; esd.outerSeqSz = SetSequence(totalSz, esd.outerSeq); totalSz += esd.outerSeqSz; if (outputSz < totalSz) return BUFFER_E; idx = 0; XMEMCPY(output + idx, esd.outerSeq, esd.outerSeqSz); idx += esd.outerSeqSz; XMEMCPY(output + idx, outerOid, outerOidSz); idx += outerOidSz; XMEMCPY(output + idx, esd.outerContent, esd.outerContentSz); idx += esd.outerContentSz; XMEMCPY(output + idx, esd.innerSeq, esd.innerSeqSz); idx += esd.innerSeqSz; XMEMCPY(output + idx, esd.version, esd.versionSz); idx += esd.versionSz; XMEMCPY(output + idx, esd.digAlgoIdSet, esd.digAlgoIdSetSz); idx += esd.digAlgoIdSetSz; XMEMCPY(output + idx, esd.singleDigAlgoId, esd.singleDigAlgoIdSz); idx += esd.singleDigAlgoIdSz; XMEMCPY(output + idx, esd.contentInfoSeq, esd.contentInfoSeqSz); idx += esd.contentInfoSeqSz; XMEMCPY(output + idx, innerOid, innerOidSz); idx += innerOidSz; XMEMCPY(output + idx, esd.innerContSeq, esd.innerContSeqSz); idx += esd.innerContSeqSz; XMEMCPY(output + idx, esd.innerOctets, esd.innerOctetsSz); idx += esd.innerOctetsSz; XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); idx += pkcs7->contentSz; XMEMCPY(output + idx, esd.certsSet, esd.certsSetSz); idx += esd.certsSetSz; XMEMCPY(output + idx, pkcs7->singleCert, pkcs7->singleCertSz); idx += pkcs7->singleCertSz; XMEMCPY(output + idx, esd.signerInfoSet, esd.signerInfoSetSz); idx += esd.signerInfoSetSz; XMEMCPY(output + idx, esd.signerInfoSeq, esd.signerInfoSeqSz); idx += esd.signerInfoSeqSz; XMEMCPY(output + idx, esd.signerVersion, esd.signerVersionSz); idx += esd.signerVersionSz; XMEMCPY(output + idx, esd.issuerSnSeq, esd.issuerSnSeqSz); idx += esd.issuerSnSeqSz; XMEMCPY(output + idx, esd.issuerName, esd.issuerNameSz); idx += esd.issuerNameSz; XMEMCPY(output + idx, pkcs7->issuer, pkcs7->issuerSz); idx += pkcs7->issuerSz; XMEMCPY(output + idx, esd.issuerSn, esd.issuerSnSz); idx += esd.issuerSnSz; XMEMCPY(output + idx, esd.signerDigAlgoId, esd.signerDigAlgoIdSz); idx += esd.signerDigAlgoIdSz; /* SignerInfo:Attributes */ if (pkcs7->signedAttribsSz != 0) { XMEMCPY(output + idx, esd.signedAttribSet, esd.signedAttribSetSz); idx += esd.signedAttribSetSz; XMEMCPY(output + idx, flatSignedAttribs, flatSignedAttribsSz); idx += flatSignedAttribsSz; XFREE(flatSignedAttribs, 0, NULL); } XMEMCPY(output + idx, esd.digEncAlgoId, esd.digEncAlgoIdSz); idx += esd.digEncAlgoIdSz; XMEMCPY(output + idx, esd.signerDigest, esd.signerDigestSz); idx += esd.signerDigestSz; XMEMCPY(output + idx, esd.encContentDigest, esd.encContentDigestSz); idx += esd.encContentDigestSz; return idx; }
int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt, int saltLen, int iterations, int kLen, int hashType, int id) { /* all in bytes instead of bits */ word32 u, v, dLen, pLen, iLen, sLen, totalLen; int dynamic = 0; int ret = 0; int i; byte *D, *S, *P, *I; #ifdef CYASSL_SMALL_STACK byte staticBuffer[1]; /* force dynamic usage */ #else byte staticBuffer[1024]; #endif byte* buffer = staticBuffer; #ifdef CYASSL_SMALL_STACK byte* Ai; byte* B; #else byte Ai[PBKDF_DIGEST_SIZE]; byte B[PBKDF_DIGEST_SIZE]; #endif if (!iterations) iterations = 1; if (hashType == MD5) { v = MD5_BLOCK_SIZE; u = MD5_DIGEST_SIZE; } else if (hashType == SHA) { v = SHA_BLOCK_SIZE; u = SHA_DIGEST_SIZE; } #ifndef NO_SHA256 else if (hashType == SHA256) { v = SHA256_BLOCK_SIZE; u = SHA256_DIGEST_SIZE; } #endif #ifdef CYASSL_SHA512 else if (hashType == SHA512) { v = SHA512_BLOCK_SIZE; u = SHA512_DIGEST_SIZE; } #endif else return BAD_FUNC_ARG; #ifdef CYASSL_SMALL_STACK Ai = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (Ai == NULL) return MEMORY_E; B = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (B == NULL) { XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; } #endif dLen = v; sLen = v * ((saltLen + v - 1) / v); if (passLen) pLen = v * ((passLen + v - 1) / v); else pLen = 0; iLen = sLen + pLen; totalLen = dLen + sLen + pLen; if (totalLen > sizeof(staticBuffer)) { buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY); if (buffer == NULL) { #ifdef CYASSL_SMALL_STACK XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return MEMORY_E; } dynamic = 1; } D = buffer; S = D + dLen; P = S + sLen; I = S; XMEMSET(D, id, dLen); for (i = 0; i < (int)sLen; i++) S[i] = salt[i % saltLen]; for (i = 0; i < (int)pLen; i++) P[i] = passwd[i % passLen]; while (kLen > 0) { word32 currentLen; mp_int B1; if (hashType == MD5) { Md5 md5; InitMd5(&md5); Md5Update(&md5, buffer, totalLen); Md5Final(&md5, Ai); for (i = 1; i < iterations; i++) { Md5Update(&md5, Ai, u); Md5Final(&md5, Ai); } } else if (hashType == SHA) { Sha sha; ret = InitSha(&sha); if (ret != 0) break; ShaUpdate(&sha, buffer, totalLen); ShaFinal(&sha, Ai); for (i = 1; i < iterations; i++) { ShaUpdate(&sha, Ai, u); ShaFinal(&sha, Ai); } } #ifndef NO_SHA256 else if (hashType == SHA256) { Sha256 sha256; ret = InitSha256(&sha256); if (ret != 0) break; ret = Sha256Update(&sha256, buffer, totalLen); if (ret != 0) break; ret = Sha256Final(&sha256, Ai); if (ret != 0) break; for (i = 1; i < iterations; i++) { ret = Sha256Update(&sha256, Ai, u); if (ret != 0) break; ret = Sha256Final(&sha256, Ai); if (ret != 0) break; } } #endif #ifdef CYASSL_SHA512 else if (hashType == SHA512) { Sha512 sha512; ret = InitSha512(&sha512); if (ret != 0) break; ret = Sha512Update(&sha512, buffer, totalLen); if (ret != 0) break; ret = Sha512Final(&sha512, Ai); if (ret != 0) break; for (i = 1; i < iterations; i++) { ret = Sha512Update(&sha512, Ai, u); if (ret != 0) break; ret = Sha512Final(&sha512, Ai); if (ret != 0) break; } } #endif for (i = 0; i < (int)v; i++) B[i] = Ai[i % u]; if (mp_init(&B1) != MP_OKAY) ret = MP_INIT_E; else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY) ret = MP_READ_E; else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY) ret = MP_ADD_E; if (ret != 0) { mp_clear(&B1); break; } for (i = 0; i < (int)iLen; i += v) { int outSz; mp_int i1; mp_int res; if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) { ret = MP_INIT_E; break; } if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY) ret = MP_READ_E; else if (mp_add(&i1, &B1, &res) != MP_OKAY) ret = MP_ADD_E; else if ( (outSz = mp_unsigned_bin_size(&res)) < 0) ret = MP_TO_E; else { if (outSz > (int)v) { /* take off MSB */ byte tmp[129]; ret = mp_to_unsigned_bin(&res, tmp); XMEMCPY(I + i, tmp + 1, v); } else if (outSz < (int)v) { XMEMSET(I + i, 0, v - outSz); ret = mp_to_unsigned_bin(&res, I + i + v - outSz); } else ret = mp_to_unsigned_bin(&res, I + i); } mp_clear(&i1); mp_clear(&res); if (ret < 0) break; } currentLen = min(kLen, (int)u); XMEMCPY(output, Ai, currentLen); output += currentLen; kLen -= currentLen; mp_clear(&B1); } if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY); #ifdef CYASSL_SMALL_STACK XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; }