예제 #1
0
파일: hash.c 프로젝트: coreboot/chrome-ec
uint16_t _cpri__HashBlock(TPM_ALG_ID alg, uint32_t in_len, uint8_t *in,
			uint32_t out_len, uint8_t *out)
{
	uint8_t digest[SHA_DIGEST_MAX_BYTES];
	const uint16_t digest_len = _cpri__GetDigestSize(alg);

	if (digest_len == 0)
		return 0;

	switch (alg) {
	case TPM_ALG_SHA1:
		DCRYPTO_SHA1_hash(in, in_len, digest);
		break;

	case TPM_ALG_SHA256:
		DCRYPTO_SHA256_hash(in, in_len, digest);
		break;
/* TODO: add support for SHA384 and SHA512
 *
 *	case TPM_ALG_SHA384:
 *		DCRYPTO_SHA384_hash(in, in_len, p);
 *		break;
 *	case TPM_ALG_SHA512:
 *		DCRYPTO_SHA512_hash(in, in_len, p);
 *		break; */
	default:
		FAIL(FATAL_ERROR_INTERNAL);
		break;
	}

	out_len = MIN(out_len, digest_len);
	memcpy(out, digest, out_len);
	return out_len;
}
예제 #2
0
//*** _cpri__StartHash()
// Functions starts a hash stack
// Start a hash stack and returns the digest size. As a side effect, the
// value of 'stateSize' in hashState is updated to indicate the number of bytes
// of state that were saved. This function calls GetHashServer() and that function
// will put the TPM into failure mode if the hash algorithm is not supported.
// return type:     CRTYP_RESULT
//  0           hash is TPM_ALG_NULL
// >0           digest size
UINT16
_cpri__StartHash(
    TPM_ALG_ID hashAlg,         // IN: hash algorithm
    BOOL sequence,              // IN: TRUE if the state should be saved
    CPRI_HASH_STATE *hashState  // OUT: the state of hash stack.
    )
{
    OSSL_HASH_STATE *state = (OSSL_HASH_STATE *)&hashState->state;
    const HASH_INFO *hashInfo = GetHashInfoPointer(hashAlg);
    UINT16 retVal = 0;

    // Not supported
    pAssert(sequence == FALSE);

    // Valid algorithm?
    if (hashInfo == NULL)
    {
        goto Cleanup;
    }

    if (BCryptCreateHash(g_hAlg[GetHashIndex(hashAlg)], &state->hHash, NULL, 0, NULL, 0, 0) != 0)
    {
        goto Cleanup;
    }

    retVal = _cpri__GetDigestSize(hashAlg);
    hashState->hashAlg = hashAlg;

Cleanup:
    return retVal;
}
예제 #3
0
파일: tsecrypto.c 프로젝트: chava33/tpm_2
static TPM_RC TSE_MGF1(unsigned char       	*mask,
		       uint32_t            	maskLen,
		       const unsigned char 	*mgfSeed,
		       uint16_t			mgfSeedlen,
		       TPMI_ALG_HASH 		halg)
{
    TPM_RC 		rc = 0;
    unsigned char       counter[4];     /* 4 octets */
    uint32_t	        count;          /* counter as an integral type */
    uint32_t		outLen;
    TPMT_HA 		digest;
    uint16_t 		digestSize = _cpri__GetDigestSize(halg);
    
    digest.hashAlg = halg;
    
#if 0
    if (rc == 0) {
        /* this is possible with arrayLen on a 64 bit architecture, comment to quiet beam */
        if ((maskLen / TPM_DIGEST_SIZE) > 0xffffffff) {        /*constant condition*/
            if (tseVerbose) printf("TSE_MGF1: Error (fatal), Output length too large for 32 bit counter\n");
            rc = TPM_FAIL;              /* should never occur */
        }
    }
#endif
    /* 1.If l > 2^32(hLen), output "mask too long" and stop. */
    /* NOTE Checked by caller */
    /* 2. Let T be the empty octet string. */
    /* 3. For counter from 0 to [masklen/hLen] - 1, do the following: */
    for (count = 0, outLen = 0 ; (rc == 0) && (outLen < maskLen) ; count++) {
	/* a. Convert counter to an octet string C of length 4 octets - see Section 4.1 */
	/* C = I2OSP(counter, 4) NOTE Basically big endian */
        uint32_t count_n = htonl(count);
	memcpy(counter, &count_n, 4);
	/* b.Concatenate the hash of the seed mgfSeed and C to the octet string T: */
	/* T = T || Hash (mgfSeed || C) */
	/* If the entire digest is needed for the mask */
	if ((outLen + digestSize) < maskLen) {
	    rc = TSE_Hash_Generate(&digest,
				   mgfSeedlen, mgfSeed,
				   4, counter,
				   0, NULL);
	    memcpy(mask + outLen, &digest.digest, digestSize);
	    outLen += digestSize;
	}
	/* if the mask is not modulo TPM_DIGEST_SIZE, only part of the final digest is needed */
	else {
	    /* hash to a temporary digest variable */
	    rc = TSE_Hash_Generate(&digest,
				   mgfSeedlen, mgfSeed,
				   4, counter,
				   0, NULL);
	    /* copy what's needed */
	    memcpy(mask + outLen, &digest.digest, maskLen - outLen);
	    outLen = maskLen;           /* outLen = outLen + maskLen - outLen */
	}
    }
    /* 4.Output the leading l octets of T as the octet string mask. */
    return rc;
}
예제 #4
0
int main(int argc, char *argv[])
{
    TPM_RC		rc = 0;
    int			i;    			/* argc iterator */
    char 		*prc = NULL;		/* pointer return code */
    const char 		*inFilename = NULL;
    const char 		*outFilename = NULL;
    FILE 		*inFile = NULL;
    FILE 		*outFile = NULL;
    UINT32           	sizeInBytes;		/* hash algorithm mapped to size */
    uint32_t	  	pcrmask = 0;		/* pcr register mask */
    TPML_PCR_SELECTION	pcrs;
    unsigned int 	pcrCount = 0;
    TPMU_HA		pcr[IMPLEMENTATION_PCR];	/* all the PCRs */
    int			pr = FALSE;
    TPMT_HA 		digest;
    uint8_t		pcrBytes[IMPLEMENTATION_PCR * MAX_DIGEST_SIZE];
    UINT16		pcrLength;

    /* command line defaults */
    digest.hashAlg = TPM_ALG_SHA256;

    ERR_load_crypto_strings ();
    OpenSSL_add_all_algorithms ();

    for (i=1 ; (i<argc) && (rc == 0) ; i++) {
	if (strcmp(argv[i],"-halg") == 0) {
	    i++;
	    if (i < argc) {
		if (strcmp(argv[i],"sha256") == 0) {
		    digest.hashAlg = TPM_ALG_SHA256;
		}
		else if (strcmp(argv[i],"sha1") == 0) {
		    digest.hashAlg = TPM_ALG_SHA1;
		}
		else {
		    printf("Bad parameter for -halg\n");
		    printUsage();
		}
	    }
	    else {
		printf("Missing parameter for -hi\n");
		printUsage();
	    }
	}
	else if (strcmp(argv[i],"-bm") == 0) {
	    i++;
	    if (i < argc) {
		if (1 != sscanf(argv[i], "%x", &pcrmask)) {
		    printf("Invalid -bm argument '%s'\n", argv[i]);
		    printUsage();
		}
	    }
	    else {
		printf("-bm option needs a value\n");
		printUsage();
	    }
	}
	else if (strcmp(argv[i],"-of") == 0) {
	    i++;
	    if (i < argc) {
		outFilename = argv[i];
	    }
	    else {
		printf("-of option needs a value\n");
		printUsage();
	    }
	}
	else if (strcmp(argv[i],"-if") == 0) {
	    i++;
	    if (i < argc) {
		inFilename = argv[i];
	    }
	    else {
		printf("-if option needs a value\n");
		printUsage();
	    }
	}
	else if (strcmp(argv[i],"-pr") == 0) {
	    pr = TRUE;
	}
	else if (strcmp(argv[i],"-h") == 0) {
	    printUsage();
	}
	else if (strcmp(argv[i],"-v") == 0) {
	    verbose = TRUE;
	    TSE_SetProperty(TPM_TRACE_LEVEL, "2");
	}
	else {
	    printf("\n%s is not a valid option\n", argv[i]);
	    printUsage();
	}
    }
    if (pcrmask == 0) {
	printf("Missing handle parameter -bm\n");
	printUsage();
    }
    if (inFilename == NULL) {
	printf("Missing handle parameter -if\n");
	printUsage();
    }
    /* open the input file */
    if (rc == 0) {
	inFile = fopen(inFilename, "r");
	if (inFile == NULL) {
	    printf("Error opening %s for %s, %s\n", inFilename, "r", strerror(errno));
	    rc = EXIT_FAILURE;
	}
    }
    if (rc == 0) {
	sizeInBytes = _cpri__GetDigestSize(digest.hashAlg);
    }
    /* Table 102 - Definition of TPML_PCR_SELECTION Structure */
    if (rc == 0) {
	pcrs.count = 1;		/* hard code one hash algorithm */
	/* Table 85 - Definition of TPMS_PCR_SELECTION Structure - pcrSelections */
	pcrs.pcrSelections[0].hash = digest.hashAlg;
	pcrs.pcrSelections[0].sizeofSelect= 3;	/* hard code 24 pcrs */
	/* TCG always marshals lower PCR first */
	pcrs.pcrSelections[0].pcrSelect[0] = (pcrmask >>  0) & 0xff;
	pcrs.pcrSelections[0].pcrSelect[1] = (pcrmask >>  8) & 0xff;
	pcrs.pcrSelections[0].pcrSelect[2] = (pcrmask >> 16) & 0xff;
    }
예제 #5
0
파일: tsecrypto.c 프로젝트: chava33/tpm_2
TPM_RC TSE_RSA_padding_add_PKCS1_OAEP(unsigned char *em, uint32_t emLen,
				      const unsigned char *from, uint32_t fLen,
				      const unsigned char *p,
				      int plen,
				      TPMI_ALG_HASH halg)	
{	
    TPM_RC		rc = 0;
    TPMT_HA 		lHash;
    unsigned char 	*db;
    
    unsigned char *dbMask = NULL;			/* freed @1 */
    unsigned char *seed = NULL;				/* freed @2 */
    unsigned char *maskedDb;
    unsigned char *seedMask;
    unsigned char *maskedSeed;

    uint16_t hlen = _cpri__GetDigestSize(halg);
    
    /* 1.a. If the length of L is greater than the input limitation for */
    /* the hash function (2^61-1 octets for SHA-1) then output "parameter */
    /* string too long" and stop. */
    if (rc == 0) {
	if (plen > 0xffff) {
	    if (tseVerbose) printf("TSE_RSA_padding_add_PKCS1_OAEP: Error, "
				   "label %u too long\n", plen);
	    rc = TSE_RC_RSA_PADDING;
	}	    
    }
    /* 1.b. If ||M|| > emLen-2hLen-1 then output "message too long" and stop. */
    if (rc == 0) {
	if (emLen < ((2 * hlen) + 2 + fLen)) {
	    if (tseVerbose) printf("TSE_RSA_padding_add_PKCS1_OAEP: Error, "
				   "message length %u too large for encoded length %u\n",
				   fLen, emLen);
	    rc = TSE_RC_RSA_PADDING;
	}
    }
    /* 2.a. Let lHash = Hash(L), an octet string of length hLen. */
    if (rc == 0) {
	lHash.hashAlg = halg;
	rc = TSE_Hash_Generate(&lHash,
			       plen, p,
			       0, NULL);
    }
    if (rc == 0) {
	/* 2.b. Generate an octet string PS consisting of emLen-||M||-2hLen-2 zero octets. The length of
	   PS may be 0. */
	/* 2.c. Concatenate lHash, PS, a single octet of 0x01 the message M, to form a data block DB as:
	   DB = lHash || PS || 01 || M */
	/* NOTE Since db is eventually maskedDb, part of em, create directly in em */
	db = em + hlen + 1;
	memcpy(db, &lHash.digest, hlen);			/* lHash */
	/* PSlen = emlen - flen - (2 * hlen) - 2 */
	memset(db + hlen, 0,					/* PS */
	       emLen - fLen - (2 * hlen) - 2);
	/* position of 0x01 in db is
	   hlen + PSlen =
	   hlen + emlen - flen - (2 * hlen) - 2 = 
	   emlen - hlen - flen - 2 */
	db[emLen - fLen - hlen - 2] = 0x01;
	memcpy(db + emLen - fLen - hlen - 1, from, fLen);	/* M */
    }
    /* 2.d. Generate a random octet string seed of length hLen. */
    if (rc == 0) {
	rc = TSE_Malloc(&seed, hlen);
    }
    if (rc == 0) {
	rc = TSE_RandBytes(seed, hlen);
    }
    if (rc == 0) {
	rc = TSE_Malloc(&dbMask, emLen - hlen - 1);
    }
    if (rc == 0) {
	/* 2.e. Let dbMask = MGF(seed, emLen-hLen-1). */
	rc = TSE_MGF1(dbMask, emLen - hlen -1,	/* dbLen */
		      seed, hlen,
		      halg);
    }
    if (rc == 0) {
	/* 2.f. Let maskedDB = DB xor dbMask. */
	/* NOTE Since maskedDB is eventually em, XOR directly to em */
	maskedDb = em + hlen + 1;
	TSE_XOR(maskedDb, db, dbMask, emLen - hlen -1);
	/* 2.g. Let seedMask = MGF(maskedDB, hLen). */
	/* NOTE Since seedMask is eventually em, create directly to em */
	seedMask = em + 1;
	rc = TSE_MGF1(seedMask, hlen,
		      maskedDb, emLen - hlen - 1,
		      halg);
    }
    if (rc == 0) {
	/* 2.h. Let maskedSeed = seed xor seedMask. */
	/* NOTE Since maskedSeed is eventually em, create directly to em */
	maskedSeed = em + 1;
	TSE_XOR(maskedSeed, seed, seedMask, hlen);
	/* 2.i. 0x00, maskedSeed, and maskedDb to form EM */
	/* NOTE Created directly in em */
    }
    free(dbMask);		/* @1 */
    free(seed);			/* @2 */
    return rc;
}