THash *HashInit(char *Type) { THash *Hash=NULL; Hash=(THash *) calloc(1,sizeof(THash)); Hash->Type=CopyStr(Hash->Type,Type); if (strcasecmp(Type,"md5")==0) HashInitMD5(Hash, 0); else if (strcasecmp(Type,"sha")==0) HashInitSHA(Hash, 0); else if (strcasecmp(Type,"sha1")==0) HashInitSHA(Hash, 0); else if (strcasecmp(Type,"sha256")==0) HashInitSHA(Hash, 256); else if (strcasecmp(Type,"sha512")==0) HashInitSHA(Hash, 512); else if (strcasecmp(Type,"whirl")==0) HashInitWhirlpool(Hash, 0); else if (strcasecmp(Type,"whirlpool")==0) HashInitWhirlpool(Hash, 0); else if (strcasecmp(Type,"jh-224")==0) HashInitJH(Hash,224); else if (strcasecmp(Type,"jh-256")==0) HashInitJH(Hash,256); else if (strcasecmp(Type,"jh-384")==0) HashInitJH(Hash,384); else if (strcasecmp(Type,"jh-512")==0) HashInitJH(Hash,512); //else if (strcasecmp(Type,"crc32")==0) HashInitCRC(Hash, 0); else if (strncasecmp(Type,"hmac-",5)==0) HMACInit(Hash); else { HashDestroy(Hash); Hash=NULL; } return(Hash); }
// Authenticates just one arbitrarily sized chunk of data void HMACOnce(const unsigned char* key, const uint8_t klen, const unsigned char* data, int len) { HMACInit(key, klen); while (len>=0) { HMACBlock(data, len>SHA1_BLOCKSIZE?SHA1_BLOCKSIZE:len); len -= SHA1_BLOCKSIZE; data += SHA1_BLOCKSIZE; } HMACDone(); }
HASH *HashInit(const char *Type) { HASH *Hash=NULL; char *InitialType=NULL; Hash=(HASH *) calloc(1,sizeof(HASH)); Hash->Type=CopyStr(Hash->Type,Type); strrep(Hash->Type,',',' '); GetToken(Hash->Type,"\\S",&InitialType,0); if (strcasecmp(InitialType,"md5")==0) HashInitMD5(Hash, 0); else if (strcasecmp(InitialType,"sha")==0) HashInitSHA(Hash, 0); else if (strcasecmp(InitialType,"sha1")==0) HashInitSHA(Hash, 0); else if (strcasecmp(InitialType,"sha256")==0) HashInitSHA(Hash, 256); else if (strcasecmp(InitialType,"sha512")==0) HashInitSHA(Hash, 512); else if (strcasecmp(InitialType,"sha-256")==0) HashInitSHA(Hash, 256); else if (strcasecmp(InitialType,"sha-512")==0) HashInitSHA(Hash, 512); else if (strcasecmp(InitialType,"whirl")==0) HashInitWhirlpool(Hash, 0); else if (strcasecmp(InitialType,"whirlpool")==0) HashInitWhirlpool(Hash, 0); else if (strcasecmp(InitialType,"jh224")==0) HashInitJH(Hash,224); else if (strcasecmp(InitialType,"jh256")==0) HashInitJH(Hash,256); else if (strcasecmp(InitialType,"jh384")==0) HashInitJH(Hash,384); else if (strcasecmp(InitialType,"jh512")==0) HashInitJH(Hash,512); else if (strcasecmp(InitialType,"jh-224")==0) HashInitJH(Hash,224); else if (strcasecmp(InitialType,"jh-256")==0) HashInitJH(Hash,256); else if (strcasecmp(InitialType,"jh-384")==0) HashInitJH(Hash,384); else if (strcasecmp(InitialType,"jh-512")==0) HashInitJH(Hash,512); //else if (strcasecmp(InitialType,"crc32")==0) HashInitCRC(Hash, 0); else if (strncasecmp(InitialType,"hmac-",5)==0) HMACInit(Hash); else { RaiseError(0, "HashInit", "Unsupported Hash Type '%s'",InitialType); HashDestroy(Hash); Hash=NULL; } DestroyString(InitialType); return(Hash); }
int hmactest(void) { test_data_t td[7]; SHA1_CTX sha; uchar_t digest[20]; int fail; int num; int i; td[0].keylen = 20; getxdata(td[0].key, "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", td[0].keylen); td[0].datalen = 8; (void) strcpy((char *)td[0].data, "Hi There"); getxdata(td[0].digest, "b617318655057264e28bc0b6fb378c8ef146be00", 20); td[1].keylen = 4; (void) strcpy((char *)td[1].key, "Jefe"); td[1].datalen = 28; (void) strcpy((char *)td[1].data, "what do ya want for nothing?"); getxdata(td[1].digest, "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79", 20); td[2].keylen = 20; getxdata(td[2].key, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", td[2].keylen); td[2].datalen = 50; getxdata(td[2].data, "ddddddddddddddddddddddddddddddddddddddddddddd" "ddddddddddddddddddddddddddddddddddddddddddddddddddddddd", 50); getxdata(td[2].digest, "125d7342b9ac11cd91a39af48aa17b4f63f175d3", 20); td[3].keylen = 25; getxdata(td[3].key, "0102030405060708090a0b0c0d0e0f1011121314151617" "1819", td[3].keylen); td[3].datalen = 50; getxdata(td[3].data, "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", td[3].datalen); getxdata(td[3].digest, "4c9007f4026250c6bc8414f9bf50c86c2d7235da", 20); td[4].keylen = 20; getxdata(td[4].key, "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", td[4].keylen); td[4].datalen = 20; (void) strcpy((char *)td[4].data, "Test With Truncation"); getxdata(td[4].digest, "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04", 20); td[5].keylen = 80; getxdata(td[5].key, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", td[5].keylen); td[5].datalen = 54; (void) strcpy((char *)td[5].data, "Test Using Larger Than Block-Size Key - Hash Key First"); getxdata(td[5].digest, "aa4ae5e15272d00e95705637ce8a3b55ed402112", 20); td[6].keylen = 80; getxdata(td[6].key, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", td[6].keylen); td[6].datalen = 73; (void) strcpy((char *)td[6].data, "Test Using Larger Than Block-Size Key and Larger Than One " "Block-Size Data"); getxdata(td[6].digest, "e8e99d0f45237d786d6bbaa7965c7808bbff1a91", 20); num = sizeof (td) / sizeof (test_data_t); for (i = 0; i < num; i++) { fail = 0; (void) printf("Test #%d ", i); HMACInit(&sha, td[i].key, td[i].keylen); HMACUpdate(&sha, td[i].data, td[i].datalen); HMACFinal(&sha, td[i].key, td[i].keylen, digest); if (bcmp(digest, td[i].digest, 20) != 0) { (void) printf("FAILED\n"); fail++; } else { (void) printf("PASSED\n"); } } return (fail); }
/* * This routine generates a random client key of the type * defined by 'ka' and stores it in the client keystore. * file. * * Returns: * KEYGEN_SUCCESS or KEYGEN_ERROR. */ static int client_gen_key(const char *filename, wbku_key_attr_t *ka, const char *net, const char *cid) { int fd; FILE *cli_fp = NULL; FILE *mas_fp; fpos_t pos; uint8_t cli_key[WANBOOT_MAXKEYLEN]; uint8_t mas_key[WANBOOT_HMAC_KEY_SIZE]; SHA1_CTX ctx; char cid_buf[PATH_MAX]; boolean_t exists = B_FALSE; wbku_retcode_t ret; /* * If the file already exists (possibly via keymgmt), then open * the file for update. Otherwise create it and open it for * for writing. */ fd = open(filename, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR); if (fd < 0) { if (errno == EEXIST) { cli_fp = fopen(filename, "r+"); exists = B_TRUE; } } else { if ((cli_fp = fdopen(fd, "w")) == NULL) { (void) close(fd); } } if (cli_fp == NULL) { wbku_printerr("Cannot open client keystore"); return (KEYGEN_ERROR); } /* * Generate the key. Encryption keys can be generated by simply * calling gen_key(). An HMAC SHA1 key will be generated by * hashing the master key. */ switch (ka->ka_type) { case WBKU_KEY_3DES: case WBKU_KEY_AES_128: if (gen_key(ka, cli_key) != KEYGEN_SUCCESS) { (void) fclose(cli_fp); return (KEYGEN_ERROR); } break; case WBKU_KEY_HMAC_SHA1: /* * Follow RFC 3118 Appendix A's algorithm to generate * the HMAC/SHA1 client key. */ /* * Open the master keystore for reading only. */ if ((mas_fp = fopen(MASTER_KEY_FILE, "r")) == NULL) { wbku_printerr("Cannot open master keystore"); (void) fclose(cli_fp); return (KEYGEN_ERROR); } /* * Find the master key. */ ret = wbku_find_key(mas_fp, NULL, ka, mas_key, B_TRUE); if (ret != WBKU_SUCCESS) { if (ret == WBKU_NOKEY) { wbku_printerr("Cannot create a client key " "without first creating a master key\n"); } else { wbku_printerr("%s\n", wbku_retmsg(ret)); } (void) fclose(mas_fp); (void) fclose(cli_fp); return (KEYGEN_ERROR); } (void) fclose(mas_fp); /* * Now generate the client's unique ID buffer. */ if (strlcpy(cid_buf, net, PATH_MAX) >= PATH_MAX || strlcat(cid_buf, cid, PATH_MAX) >= PATH_MAX) { wbku_printerr("Unique id for client is too big\n"); (void) fclose(cli_fp); return (KEYGEN_ERROR); } /* * Hash the buffer to create the client key. */ HMACInit(&ctx, mas_key, WANBOOT_HMAC_KEY_SIZE); HMACUpdate(&ctx, (uint8_t *)cid_buf, strlen(cid_buf)); HMACFinal(&ctx, mas_key, WANBOOT_HMAC_KEY_SIZE, cli_key); break; case WBKU_KEY_RSA: wbku_printerr("Cannot generate RSA key using keygen\n"); (void) fclose(cli_fp); return (KEYGEN_ERROR); default: wbku_printerr("Internal error\n"); (void) fclose(cli_fp); return (KEYGEN_ERROR); } /* * Look to see if a client key of this type exists and if * it does note its position in the file. */ ret = WBKU_NOKEY; if (exists) { ret = wbku_find_key(cli_fp, &pos, ka, NULL, B_FALSE); if (ret != WBKU_SUCCESS && ret != WBKU_NOKEY) { wbku_printerr("%s\n", wbku_retmsg(ret)); (void) fclose(cli_fp); return (KEYGEN_ERROR); } } /* * If wbku_find_key() did not find the key position for us, * then we should set position to the end of the file. */ if (ret == WBKU_NOKEY && (fseek(cli_fp, 0, SEEK_END) != 0 || fgetpos(cli_fp, &pos) != 0)) { wbku_printerr("Internal error"); (void) fclose(cli_fp); return (KEYGEN_ERROR); } /* * Write the key. */ ret = wbku_write_key(cli_fp, &pos, ka, cli_key, B_FALSE); if (ret != WBKU_SUCCESS) { wbku_printerr("%s\n", wbku_retmsg(ret)); (void) fclose(cli_fp); return (KEYGEN_ERROR); } (void) fclose(cli_fp); (void) printf(gettext("A new client %s key has been generated\n"), ka->ka_str); return (KEYGEN_SUCCESS); }