예제 #1
0
static char *
digest_end(DIGEST_CTX *c, char *buf)
{

	switch (digesttype) {
	case DIGEST_MD5:
		return (MD5End(&(c->MD5), buf));
	case DIGEST_RIPEMD160:
		return (RIPEMD160_End(&(c->RIPEMD160), buf));
	case DIGEST_SHA1:
		return (SHA1_End(&(c->SHA1), buf));
	case DIGEST_SHA256:
		return (SHA256_End(&(c->SHA256), buf));
	case DIGEST_SHA512:
		return (SHA512_End(&(c->SHA512), buf));
	default:
		return (NULL);
	}
}
예제 #2
0
파일: sha2hl.c 프로젝트: Rod-O/pkgsrc
char           *
SHA256_File(char *filename, char *buf)
{
	unsigned char          buffer[BUFSIZ * 20];
	SHA256_CTX      ctx;
	int             fd, num, oerrno;

	_DIAGASSERT(filename != NULL);
	/* XXX: buf may be NULL ? */

	SHA256_Init(&ctx);

	if ((fd = open(filename, O_RDONLY)) < 0)
		return (0);

	while ((num = read(fd, buffer, sizeof(buffer))) > 0)
		SHA256_Update(&ctx, buffer, (size_t) num);

	oerrno = errno;
	close(fd);
	errno = oerrno;
	return (num < 0 ? 0 : SHA256_End(&ctx, buf));
}
예제 #3
0
파일: drbg.c 프로젝트: MekliCZ/positron
/*
 * This function expands the internal state of the prng to fulfill any number
 * of bytes we need for this request. We only use this call if we need more
 * than can be supplied by a single call to SHA256_HashBuf. 
 *
 * This function is specified in NIST SP 800-90 section 10.1.1.4, Hashgen
 */
static void
prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes, 
	     unsigned int no_of_returned_bytes)
{
    PRUint8 data[VSize(rng)];
    PRUint8 thisHash[SHA256_LENGTH];
    PRUint8 *lastHash = rng->lastOutput;

    PORT_Memcpy(data, V(rng), VSize(rng));
    while (no_of_returned_bytes) {
	SHA256Context ctx;
	unsigned int len;
	unsigned int carry;

 	SHA256_Begin(&ctx);
 	SHA256_Update(&ctx, data, sizeof data);
	SHA256_End(&ctx, thisHash, &len, SHA256_LENGTH);
	if (PORT_Memcmp(lastHash, thisHash, len) == 0) {
	    rng->isValid = PR_FALSE;
	    break;
	}
	if (no_of_returned_bytes < SHA256_LENGTH) {
	    len = no_of_returned_bytes;
	}
	PORT_Memcpy(returned_bytes, thisHash, len);
	lastHash = returned_bytes;
	returned_bytes += len;
	no_of_returned_bytes -= len;
	/* The carry parameter is a bool (increment or not). 
	 * This increments data if no_of_returned_bytes is not zero */
        carry = no_of_returned_bytes;
	PRNG_ADD_CARRY_ONLY(data, (sizeof data)- 1, carry);
    }
    PORT_Memcpy(rng->lastOutput, thisHash, SHA256_LENGTH);
    PORT_Memset(data, 0, sizeof data); 
    PORT_Memset(thisHash, 0, sizeof thisHash); 
}
예제 #4
0
/*
 * This function expands the internal state of the prng to fulfill any number
 * of bytes we need for this request. We only use this call if we need more
 * than can be supplied by a single call to SHA256_HashBuf. 
 *
 * This function is specified in NIST SP 800-90 section 10.1.1.4, Hashgen
 */
static void
prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes, 
	     unsigned int no_of_returned_bytes)
{
    PRUint8 data[VSize(rng)];

    PORT_Memcpy(data, V(rng), VSize(rng));
    while (no_of_returned_bytes) {
	SHA256Context ctx;
	unsigned int len;
	unsigned int carry;
	int k1;

 	SHA256_Begin(&ctx);
 	SHA256_Update(&ctx, data, sizeof data);
	SHA256_End(&ctx, returned_bytes, &len, no_of_returned_bytes);
	returned_bytes += len;
	no_of_returned_bytes -= len;
	/* The carry parameter is a bool (increment or not). 
	 * This increments data if no_of_returned_bytes is not zero */
	PRNG_ADD_CARRY_ONLY(data, (sizeof data)- 1, no_of_returned_bytes);
    }
    PORT_Memset(data, 0, sizeof data); 
}
예제 #5
0
bool
GMPLoaderImpl::Load(const char* aLibPath,
                    uint32_t aLibPathLen,
                    char* aOriginSalt,
                    uint32_t aOriginSaltLen,
                    const GMPPlatformAPI* aPlatformAPI)
{
  std::string nodeId;
#ifdef HASH_NODE_ID_WITH_DEVICE_ID
  if (aOriginSaltLen > 0) {
    string16 deviceId;
    int volumeId;
    if (!rlz_lib::GetRawMachineId(&deviceId, &volumeId)) {
      return false;
    }

    SHA256Context ctx;
    SHA256_Begin(&ctx);
    SHA256_Update(&ctx, (const uint8_t*)aOriginSalt, aOriginSaltLen);
    SHA256_Update(&ctx, (const uint8_t*)deviceId.c_str(), deviceId.size() * sizeof(string16::value_type));
    SHA256_Update(&ctx, (const uint8_t*)&volumeId, sizeof(int));
    uint8_t digest[SHA256_LENGTH] = {0};
    unsigned int digestLen = 0;
    SHA256_End(&ctx, digest, &digestLen, SHA256_LENGTH);

    // Overwrite all data involved in calculation as it could potentially
    // identify the user, so there's no chance a GMP can read it and use
    // it for identity tracking.
    memset(&ctx, 0, sizeof(ctx));
    memset(aOriginSalt, 0, aOriginSaltLen);
    volumeId = 0;
    memset(&deviceId[0], '*', sizeof(string16::value_type) * deviceId.size());
    deviceId = L"";

    if (!rlz_lib::BytesToString(digest, SHA256_LENGTH, &nodeId)) {
      return false;
    }
    // We've successfully bound the origin salt to node id.
    // rlz_lib::GetRawMachineId and/or the system functions it
    // called could have left user identifiable data on the stack,
    // so carefully zero the stack down to the guard page.
    uint8_t* top;
    uint8_t* bottom;
    if (!GetStackAfterCurrentFrame(&top, &bottom)) {
      return false;
    }
    assert(top >= bottom);
    // Inline instructions equivalent to RtlSecureZeroMemory().
    // We can't just use RtlSecureZeroMemory here directly, as in debug
    // builds, RtlSecureZeroMemory() can't be inlined, and the stack
    // memory it uses would get wiped by itself running, causing crashes.
    for (volatile uint8_t* p = (volatile uint8_t*)bottom; p < top; p++) {
      *p = 0;
    }
  } else
#endif
  {
    nodeId = std::string(aOriginSalt, aOriginSalt + aOriginSaltLen);
  }

  // Start the sandbox now that we've generated the device bound node id.
  // This must happen after the node id is bound to the device id, as
  // generating the device id requires privileges.
  if (mSandboxStarter) {
    mSandboxStarter->Start(aLibPath);
  }

  // Load the GMP.
  PRLibSpec libSpec;
  libSpec.value.pathname = aLibPath;
  libSpec.type = PR_LibSpec_Pathname;
  mLib = PR_LoadLibraryWithFlags(libSpec, 0);
  if (!mLib) {
    return false;
  }

  GMPInitFunc initFunc = reinterpret_cast<GMPInitFunc>(PR_FindFunctionSymbol(mLib, "GMPInit"));
  if (!initFunc) {
    return false;
  }

  if (initFunc(aPlatformAPI) != GMPNoErr) {
    return false;
  }

  GMPSetNodeIdFunc setNodeIdFunc = reinterpret_cast<GMPSetNodeIdFunc>(PR_FindFunctionSymbol(mLib, "GMPSetNodeId"));
  if (setNodeIdFunc) {
    setNodeIdFunc(nodeId.c_str(), nodeId.size());
  }

  mGetAPIFunc = reinterpret_cast<GMPGetAPIFunc>(PR_FindFunctionSymbol(mLib, "GMPGetAPI"));
  if (!mGetAPIFunc) {
    return false;
  }

  return true;
}
예제 #6
0
bool
GMPLoaderImpl::Load(const char* aLibPath,
                    uint32_t aLibPathLen,
                    char* aOriginSalt,
                    uint32_t aOriginSaltLen,
                    const GMPPlatformAPI* aPlatformAPI)
{
    std::string nodeId;
#ifdef HASH_NODE_ID_WITH_DEVICE_ID
    if (aOriginSaltLen > 0) {
        string16 deviceId;
        int volumeId;
        if (!rlz_lib::GetRawMachineId(&deviceId, &volumeId)) {
            return false;
        }

        SHA256Context ctx;
        SHA256_Begin(&ctx);
        SHA256_Update(&ctx, (const uint8_t*)aOriginSalt, aOriginSaltLen);
        SHA256_Update(&ctx, (const uint8_t*)deviceId.c_str(), deviceId.size() * sizeof(string16::value_type));
        SHA256_Update(&ctx, (const uint8_t*)&volumeId, sizeof(int));
        uint8_t digest[SHA256_LENGTH] = {0};
        unsigned int digestLen = 0;
        SHA256_End(&ctx, digest, &digestLen, SHA256_LENGTH);

        // Overwrite all data involved in calculation as it could potentially
        // identify the user, so there's no chance a GMP can read it and use
        // it for identity tracking.
        memset(&ctx, 0, sizeof(ctx));
        memset(aOriginSalt, 0, aOriginSaltLen);
        volumeId = 0;
        memset(&deviceId[0], '*', sizeof(string16::value_type) * deviceId.size());
        deviceId = L"";

        if (!rlz_lib::BytesToString(digest, SHA256_LENGTH, &nodeId)) {
            return false;
        }
        // We've successfully bound the origin salt to node id.
        // rlz_lib::GetRawMachineId and/or the system functions it
        // called could have left user identifiable data on the stack,
        // so carefully zero the stack down to the guard page.
        uint8_t* top;
        uint8_t* bottom;
        if (!GetStackAfterCurrentFrame(&top, &bottom)) {
            return false;
        }
        assert(top >= bottom);
        // Inline instructions equivalent to RtlSecureZeroMemory().
        // We can't just use RtlSecureZeroMemory here directly, as in debug
        // builds, RtlSecureZeroMemory() can't be inlined, and the stack
        // memory it uses would get wiped by itself running, causing crashes.
        for (volatile uint8_t* p = (volatile uint8_t*)bottom; p < top; p++) {
            *p = 0;
        }
    } else
#endif
    {
        nodeId = std::string(aOriginSalt, aOriginSalt + aOriginSaltLen);
    }

#if defined(XP_WIN) && defined(MOZ_SANDBOX)
    // If the GMP DLL is a side-by-side assembly with static imports then the DLL
    // loader will attempt to create an activation context which will fail because
    // of the sandbox. If we create an activation context before we start the
    // sandbox then this one will get picked up by the DLL loader.
    int pathLen = MultiByteToWideChar(CP_ACP, 0, aLibPath, -1, nullptr, 0);
    if (pathLen == 0) {
        return false;
    }

    wchar_t* widePath = new wchar_t[pathLen];
    if (MultiByteToWideChar(CP_ACP, 0, aLibPath, -1, widePath, pathLen) == 0) {
        delete[] widePath;
        return false;
    }

    ACTCTX actCtx = { sizeof(actCtx) };
    actCtx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
    actCtx.lpSource = widePath;
    actCtx.lpResourceName = ISOLATIONAWARE_MANIFEST_RESOURCE_ID;
    ScopedActCtxHandle actCtxHandle(CreateActCtx(&actCtx));
    delete[] widePath;
#endif

    // Start the sandbox now that we've generated the device bound node id.
    // This must happen after the node id is bound to the device id, as
    // generating the device id requires privileges.
    if (mSandboxStarter) {
        mSandboxStarter->Start(aLibPath);
    }

    // Load the GMP.
    PRLibSpec libSpec;
    libSpec.value.pathname = aLibPath;
    libSpec.type = PR_LibSpec_Pathname;
    mLib = PR_LoadLibraryWithFlags(libSpec, 0);
    if (!mLib) {
        return false;
    }

    GMPInitFunc initFunc = reinterpret_cast<GMPInitFunc>(PR_FindFunctionSymbol(mLib, "GMPInit"));
    if (!initFunc) {
        return false;
    }

    if (initFunc(aPlatformAPI) != GMPNoErr) {
        return false;
    }

    GMPSetNodeIdFunc setNodeIdFunc = reinterpret_cast<GMPSetNodeIdFunc>(PR_FindFunctionSymbol(mLib, "GMPSetNodeId"));
    if (setNodeIdFunc) {
        setNodeIdFunc(nodeId.c_str(), nodeId.size());
    }

    mGetAPIFunc = reinterpret_cast<GMPGetAPIFunc>(PR_FindFunctionSymbol(mLib, "GMPGetAPI"));
    if (!mGetAPIFunc) {
        return false;
    }

    return true;
}
예제 #7
0
int main(int argc, char **argv) {
	int		kl, l, fd, ac;
	int		quiet = 0, hash = 0;
	char		*av, *file = (char*)0;
	FILE		*IN = (FILE*)0;
	SHA256_CTX	ctx256;
	SHA384_CTX	ctx384;
	SHA512_CTX	ctx512;
	unsigned char	buf[BUFLEN];

	SHA256_Init(&ctx256);
	SHA384_Init(&ctx384);
	SHA512_Init(&ctx512);

	/* Read data from STDIN by default */
	fd = fileno(stdin);

	ac = 1;
	while (ac < argc) {
		if (*argv[ac] == '-') {
			av = argv[ac] + 1;
			if (!strcmp(av, "q")) {
				quiet = 1;
			} else if (!strcmp(av, "256")) {
				hash |= 1;
			} else if (!strcmp(av, "384")) {
				hash |= 2;
			} else if (!strcmp(av, "512")) {
				hash |= 4;
			} else if (!strcmp(av, "ALL")) {
				hash = 7;
			} else {
				usage(argv[0], "Invalid option.");
			}
			ac++;
		} else {
			file = argv[ac++];
			if (ac != argc) {
				usage(argv[0], "Too many arguments.");
			}
			if ((IN = fopen(file, "r")) == NULL) {
				perror(argv[0]);
				exit(-1);
			}
			fd = fileno(IN);
		}
	}
	if (hash == 0)
		hash = 7;	/* Default to ALL */

	kl = 0;
	while ((l = read(fd,buf,BUFLEN)) > 0) {
		kl += l;
		SHA256_Update(&ctx256, (unsigned char*)buf, l);
		SHA384_Update(&ctx384, (unsigned char*)buf, l);
		SHA512_Update(&ctx512, (unsigned char*)buf, l);
	}
	if (file) {
		fclose(IN);
	}

	if (hash & 1) {
		SHA256_End(&ctx256, buf);
		if (!quiet)
			printf("SHA-256 (%s) = ", file);
		printf("%s\n", buf);
	}
	if (hash & 2) {
		SHA384_End(&ctx384, buf);
		if (!quiet)
			printf("SHA-384 (%s) = ", file);
		printf("%s\n", buf);
	}
	if (hash & 4) {
		SHA512_End(&ctx512, buf);
		if (!quiet)
			printf("SHA-512 (%s) = ", file);
		printf("%s\n", buf);
	}

	return 1;
}
예제 #8
0
/*
========================================================================
Routine Description:
    HMAC using SHA256 hash function

Arguments:
    key             Secret key
    key_len         The length of the key in bytes
    message         Message context
    message_len     The length of message in bytes
    macLen          Request the length of message authentication code

Return Value:
    mac             Message authentication code

Note:
    None
========================================================================
*/
VOID HMAC_SHA256 (
    IN  const UINT8 Key[],
    IN  UINT KeyLen,
    IN  const UINT8 Message[],
    IN  UINT MessageLen,
    OUT UINT8 MAC[],
    IN  UINT MACLen)
{
    SHA256_CTX_STRUC sha_ctx1;
    SHA256_CTX_STRUC sha_ctx2;
    UINT8 K0[SHA256_BLOCK_SIZE];
    UINT8 Digest[SHA256_DIGEST_SIZE];
    UINT index;

    NdisZeroMemory(&sha_ctx1, sizeof(SHA256_CTX_STRUC));
    NdisZeroMemory(&sha_ctx2, sizeof(SHA256_CTX_STRUC));
    /*
     * If the length of K = B(Block size): K0 = K.
     * If the length of K > B: hash K to obtain an L byte string,
     * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
     * If the length of K < B: append zeros to the end of K to create a B-byte string K0
     */
    NdisZeroMemory(K0, SHA256_BLOCK_SIZE);
    if (KeyLen <= SHA256_BLOCK_SIZE) {
        NdisMoveMemory(K0, Key, KeyLen);
    } else {
        RT_SHA256(Key, KeyLen, K0);
    }

    /* Exclusive-Or K0 with ipad */
    /* ipad: Inner pad; the byte x��36�� repeated B times. */
    for (index = 0; index < SHA256_BLOCK_SIZE; index++)
        K0[index] ^= 0x36;
        /* End of for */

    SHA256_Init(&sha_ctx1);
    /* H(K0^ipad) */
    SHA256_Append(&sha_ctx1, K0, sizeof(K0));
    /* H((K0^ipad)||text) */
    SHA256_Append(&sha_ctx1, Message, MessageLen);
    SHA256_End(&sha_ctx1, Digest);

    /* Exclusive-Or K0 with opad and remove ipad */
    /* opad: Outer pad; the byte x��5c�� repeated B times. */
    for (index = 0; index < SHA256_BLOCK_SIZE; index++)
        K0[index] ^= 0x36^0x5c;
        /* End of for */

    SHA256_Init(&sha_ctx2);
    /* H(K0^opad) */
    SHA256_Append(&sha_ctx2, K0, sizeof(K0));
    /* H( (K0^opad) || H((K0^ipad)||text) ) */
    SHA256_Append(&sha_ctx2, Digest, SHA256_DIGEST_SIZE);
    SHA256_End(&sha_ctx2, Digest);

    if (MACLen > SHA256_DIGEST_SIZE)
        NdisMoveMemory(MAC, Digest,SHA256_DIGEST_SIZE);
    else
        NdisMoveMemory(MAC, Digest, MACLen);

} /* End of HMAC_SHA256 */
예제 #9
0
파일: drbg.c 프로젝트: MekliCZ/positron
/* 
 * Generates new random bytes and advances the internal prng state.	
 * additional bytes are only used in algorithm testing.
 * 
 * This function is specified in NIST SP 800-90 section 10.1.1.4
 */
static SECStatus
prng_generateNewBytes(RNGContext *rng, 
		PRUint8 *returned_bytes, unsigned int no_of_returned_bytes,
		const PRUint8 *additional_input,
		unsigned int additional_input_len)
{
    PRUint8 H[SHA256_LENGTH]; /* both H and w since they 
			       * aren't used concurrently */
    unsigned int carry;

    if (!rng->isValid) {
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
    }
    /* This code only triggers during tests, normal
     * prng operation does not use additional_input */
    if (additional_input){
	SHA256Context ctx;
	/* NIST SP 800-90 defines two temporaries in their calculations,
	 * w and H. These temporaries are the same lengths, and used
	 * at different times, so we use the following macro to collapse
	 * them to the same variable, but keeping their unique names for
	 * easy comparison to the spec */
#define w H
	rng->V_type = prngAdditionalDataType;
 	SHA256_Begin(&ctx);
 	SHA256_Update(&ctx, rng->V_Data, sizeof rng->V_Data);
 	SHA256_Update(&ctx, additional_input, additional_input_len);
	SHA256_End(&ctx, w, NULL, sizeof w);
	PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof w, carry)
	PORT_Memset(w, 0, sizeof w);
#undef w 
    }

    if (no_of_returned_bytes == SHA256_LENGTH) {
	/* short_cut to hashbuf and a couple of copies and clears */
	SHA256_HashBuf(returned_bytes, V(rng), VSize(rng) );
	/* continuous rng check */
	if (memcmp(rng->lastOutput, returned_bytes, SHA256_LENGTH) == 0) {
	    rng->isValid = PR_FALSE;
	}
	PORT_Memcpy(rng->lastOutput, returned_bytes, sizeof rng->lastOutput);
    } else {
    	prng_Hashgen(rng, returned_bytes, no_of_returned_bytes);
    }
    /* advance our internal state... */
    rng->V_type = prngGenerateByteType;
    SHA256_HashBuf(H, rng->V_Data, sizeof rng->V_Data);
    PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), H, sizeof H, carry)
    PRNG_ADD_BITS(V(rng), VSize(rng), rng->C, sizeof rng->C, carry);
    PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), rng->reseed_counter, 
					sizeof rng->reseed_counter, carry)
    carry = 1;
    PRNG_ADD_CARRY_ONLY(rng->reseed_counter,(sizeof rng->reseed_counter)-1, carry);

    /* if the prng failed, don't return any output, signal softoken */
    if (!rng->isValid) {
	PORT_Memset(returned_bytes, 0,  no_of_returned_bytes);
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
    }
    return SECSuccess;
}