mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-02-02 14:37:43 +00:00
391 lines
10 KiB
C
391 lines
10 KiB
C
/*
|
|
* SPDX-FileCopyrightText: Copyright (c) 2007-2012 NVIDIA CORPORATION & AFFILIATES
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
/*!
|
|
* Utility header file to generate a one-way hash from an arbitrary
|
|
* byte array, using the Secure Hashing Algorithm 1 (SHA-1) as defined
|
|
* in FIPS PUB 180-1 published April 17, 1995:
|
|
*
|
|
* https://www.itl.nist.gov/fipspubs/fip180-1.htm
|
|
*
|
|
* Some common test cases (see Appendices A and B of the above document):
|
|
*
|
|
* SHA1("abc") =
|
|
* A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
|
|
*
|
|
* SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
|
|
* 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
|
|
*/
|
|
|
|
#ifndef __NV_SHA1_H__
|
|
#define __NV_SHA1_H__
|
|
|
|
#include "nvtypes.h"
|
|
|
|
/*!
|
|
* @brief Structure used by the SHA-1 functions to maintain the state of the
|
|
* calculations.
|
|
*/
|
|
|
|
typedef struct
|
|
{
|
|
NvU32 state[5];
|
|
NvU32 count;
|
|
NvU8 buffer[128];
|
|
} Sha1Context;
|
|
|
|
|
|
/*!
|
|
* @brief Pointer to a memory accessor function for use by the SHA-1 hash
|
|
* function.
|
|
*
|
|
* Due to memory constraints in some environments where this code is executed
|
|
* (e.g., the PMU/DPU), the data that needs to be processed by the SHA-1 hash
|
|
* function may not be readily available. This function is responsible for
|
|
* copying the data into a buffer to be used by the SHA-1 function.
|
|
*
|
|
* Besides, SHA1 library can be used by many different clients, so we need to
|
|
* provide the memory accessor functions which can work in client's environment.
|
|
*
|
|
* @param[out] pBuff The buffer to copy the new data to.
|
|
* @param[in] index The desired offset to begin copying from.
|
|
* @param[in] size The requested number of bytes to be copied.
|
|
* @param[in] info Pointer to the data passed into GenerateSha1 as pData.
|
|
*
|
|
* @return The actual number of bytes copied into the buffer.
|
|
*/
|
|
|
|
typedef NvU32 Sha1CopyFunc(NvU8 *pBuff, NvU32 index, NvU32 size, void *pInfo);
|
|
|
|
|
|
/*
|
|
* The following values are defined by the SHA-1 algorithm for initial values.
|
|
*/
|
|
#define SHA1_INIT_H0 0x67452301 //!< Initial H0 value
|
|
#define SHA1_INIT_H1 0xEFCDAB89 //!< Initial H1 value
|
|
#define SHA1_INIT_H2 0x98BADCFE //!< Initial H2 value
|
|
#define SHA1_INIT_H3 0x10325476 //!< Initial H3 value
|
|
#define SHA1_INIT_H4 0xC3D2E1F0 //!< Initial H4 value
|
|
|
|
|
|
/*!
|
|
* @brief Reverses the byte order of a word; that is, switching the endianness
|
|
* of the word.
|
|
*
|
|
* @param[in] a A 32-bit word
|
|
*
|
|
* @returns The 32-bit word with its byte order reversed.
|
|
*/
|
|
|
|
#define REVERSE_BYTE_ORDER(a) \
|
|
(((a) >> 24) | ((a) << 24) | (((a) >> 8) & 0xFF00) | (((a) << 8) & 0xFF0000))
|
|
|
|
|
|
/*!
|
|
* @brief Computation step as defined by SHA-1.
|
|
*
|
|
* Unlike the 64 byte buffer version outlined in the SHA-1 algorithm, this
|
|
* function uses a 128 byte buffer to minimize the calculation needed to
|
|
* index the data.
|
|
*
|
|
* @param[in,out] pState
|
|
* Pointer to State word array.
|
|
*
|
|
* @param[in] pBuffer
|
|
* Data to operate on. 128 bytes in length. No length checking is done,
|
|
* and is assumed to have been done by the calling function.
|
|
*/
|
|
|
|
static void
|
|
_sha1Transform
|
|
(
|
|
NvU32 *pState,
|
|
NvU8 *pBuffer
|
|
)
|
|
{
|
|
NvU32 a = pState[0];
|
|
NvU32 b = pState[1];
|
|
NvU32 c = pState[2];
|
|
NvU32 d = pState[3];
|
|
NvU32 e = pState[4];
|
|
NvU32 *pBuf = (NvU32 *)pBuffer;
|
|
NvU32 *p;
|
|
NvU32 i;
|
|
NvU32 j;
|
|
NvU32 k;
|
|
|
|
for (i = 0; i < 80; i++)
|
|
{
|
|
p = &pBuf[i & 0xf];
|
|
j = p[0];
|
|
if (i < 16)
|
|
{
|
|
j = REVERSE_BYTE_ORDER(j);
|
|
}
|
|
else
|
|
{
|
|
j ^= p[2] ^ p[8] ^ p[13];
|
|
j = (j << 1) + (j >> 31);
|
|
}
|
|
p[0] = p[16] = j;
|
|
if (i < 40)
|
|
{
|
|
if (i < 20)
|
|
{
|
|
k = 0x5a827999 + ((b & (c ^ d)) ^ d);
|
|
}
|
|
else
|
|
{
|
|
k = 0x6ed9eba1 + (b ^ c ^ d);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (i < 60)
|
|
{
|
|
k = 0x8f1bbcdc + (((b | c) & d) | (b & c));
|
|
}
|
|
else
|
|
{
|
|
k = 0xca62c1d6 + (b ^ c ^ d);
|
|
}
|
|
}
|
|
j += (a << 5) + (a >> 27) + e + k;
|
|
e = d;
|
|
d = c;
|
|
c = (b << 30) + (b >> 2);
|
|
b = a;
|
|
a = j;
|
|
}
|
|
pState[0] += a;
|
|
pState[1] += b;
|
|
pState[2] += c;
|
|
pState[3] += d;
|
|
pState[4] += e;
|
|
}
|
|
|
|
|
|
/*!
|
|
* Initializes the SHA-1 context.
|
|
*
|
|
* @param[out] pContext
|
|
* Pointer to the context to initialize.
|
|
*/
|
|
|
|
static void
|
|
_sha1Initialize
|
|
(
|
|
Sha1Context *pContext
|
|
)
|
|
{
|
|
pContext->count = 0;
|
|
pContext->state[0] = SHA1_INIT_H0;
|
|
pContext->state[1] = SHA1_INIT_H1;
|
|
pContext->state[2] = SHA1_INIT_H2;
|
|
pContext->state[3] = SHA1_INIT_H3;
|
|
pContext->state[4] = SHA1_INIT_H4;
|
|
}
|
|
|
|
|
|
/*!
|
|
* @brief Divides the input buffer into multiple 64-byte buffers and computes
|
|
* the message digest for each.
|
|
*
|
|
* @param[in] pContext
|
|
* Pointer to a Sha1Context.
|
|
*
|
|
* @param[in] pData
|
|
* Pointer to the data array to compute the message digest.
|
|
*
|
|
* @param[in] len
|
|
* Size of the data.
|
|
*
|
|
* @param[in] copyFunc
|
|
* Copy routine to use.
|
|
*/
|
|
|
|
static void
|
|
_sha1Update
|
|
(
|
|
Sha1Context *pContext,
|
|
void *pData,
|
|
NvU32 len,
|
|
Sha1CopyFunc copyFunc
|
|
)
|
|
{
|
|
NvU32 buffer_offset = (pContext->count & 63);
|
|
NvU32 copy_size;
|
|
NvU32 idx = 0;
|
|
|
|
pContext->count += len;
|
|
while ((buffer_offset + len) > 63)
|
|
{
|
|
copy_size = 64 - buffer_offset;
|
|
copyFunc(&pContext->buffer[buffer_offset], idx, copy_size, pData);
|
|
_sha1Transform(pContext->state, pContext->buffer);
|
|
buffer_offset = 0;
|
|
idx += copy_size;
|
|
len -= copy_size;
|
|
}
|
|
if (len > 0)
|
|
{
|
|
copyFunc(&pContext->buffer[buffer_offset], idx, len, pData);
|
|
}
|
|
}
|
|
|
|
|
|
/*!
|
|
* @brief fill memory with zero; not all environments in which this
|
|
* code runs have memset(3).
|
|
*
|
|
* @param[out] pData
|
|
* The memory to be filled with zero
|
|
*
|
|
* @param[in] nBytes
|
|
* The number of bytes of memory to fill with zero
|
|
*/
|
|
|
|
static NV_INLINE void
|
|
_sha1MemZero
|
|
(
|
|
NvU8 *pData,
|
|
NvU32 nBytes
|
|
)
|
|
{
|
|
NvU32 i;
|
|
|
|
for (i = 0; i < nBytes; i++) {
|
|
pData[i] = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/*!
|
|
* @brief Pads the message as specified by the SHA-1 algorithm and computes
|
|
* the message digest on the final message chunk(s).
|
|
*
|
|
* @param[out] pDigest
|
|
* The SHA-1 hash values.
|
|
*
|
|
* @param[in] pContext
|
|
* Pointer to a Sha1Context.
|
|
*/
|
|
|
|
static void
|
|
_sha1Final
|
|
(
|
|
NvU8 *pDigest,
|
|
Sha1Context *pContext
|
|
)
|
|
{
|
|
NvU32 i;
|
|
NvU32 bufferOffset = (pContext->count & 63);
|
|
NvU8 *pBuffer = (NvU8*)&pContext->buffer[bufferOffset];
|
|
NvU32 *pCount;
|
|
NvU32 *pDig32;
|
|
|
|
// append padding pattern to the end of input
|
|
*pBuffer++ = 0x80;
|
|
if (bufferOffset < 56)
|
|
{
|
|
_sha1MemZero(pBuffer, 59 - bufferOffset);
|
|
}
|
|
else
|
|
{
|
|
// need an extra sha1_transform
|
|
if (bufferOffset < 63)
|
|
{
|
|
_sha1MemZero(pBuffer, 63 - bufferOffset);
|
|
}
|
|
_sha1Transform(pContext->state, pContext->buffer);
|
|
_sha1MemZero(pContext->buffer, 60);
|
|
}
|
|
|
|
// set final count (this is the number of *bits* not *bytes*)
|
|
pCount = (NvU32*)&pContext->buffer[15 << 2];
|
|
*pCount = REVERSE_BYTE_ORDER(pContext->count << 3);
|
|
|
|
_sha1Transform(pContext->state, pContext->buffer);
|
|
|
|
// output hash with each dword in big endian
|
|
if (pDigest)
|
|
{
|
|
pDig32 = (NvU32*) pDigest;
|
|
for (i = 0; i < 5; i++)
|
|
{
|
|
pDig32[i] = REVERSE_BYTE_ORDER(pContext->state[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*!
|
|
* @brief Generates the SHA-1 hash value on the data provided.
|
|
*
|
|
* The function does not manipulate the source data directly, as it may not
|
|
* have direct access to it. Therefore, it relies upon the copy function to
|
|
* copy segments of the data into a local buffer before any manipulation takes
|
|
* place.
|
|
*
|
|
* @param[out] pHash
|
|
* Pointer to store the hash array. The buffer must be 20 bytes in
|
|
* length, and the result is stored in big endian format.
|
|
*
|
|
* @param[in] pData
|
|
* The source data array to transform. The actual values and make-up
|
|
* of this parameter are dependent on the copy function.
|
|
*
|
|
* @param[in] nBytes
|
|
* The size, in bytes, of the source data.
|
|
*
|
|
* @param[in] copyFunc
|
|
* The function responsible for copying data from the source
|
|
* for use by the sha1 function. It is possible for the data
|
|
* to exist outside the current execution environment (e.g.,
|
|
* the PMU, and the data to hash are in system memory), so
|
|
* the function will never directly manipulate the source
|
|
* data.
|
|
*/
|
|
|
|
#define NV_SHA1_BLOCK_LENGTH 64
|
|
#define NV_SHA1_DIGEST_LENGTH 20
|
|
|
|
static void
|
|
sha1Generate
|
|
(
|
|
NvU8 pHash[NV_SHA1_DIGEST_LENGTH],
|
|
void *pData,
|
|
NvU32 nBytes,
|
|
Sha1CopyFunc copyFunc
|
|
)
|
|
{
|
|
Sha1Context context;
|
|
|
|
_sha1Initialize(&context);
|
|
_sha1Update(&context, pData, nBytes, copyFunc);
|
|
_sha1Final(pHash, &context);
|
|
}
|
|
|
|
|
|
#endif /* __NV_SHA1_H__ */
|