#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#include "seq_sha1.cuh"

#ifdef HMAC_SHA1_DATA_PROBLEMS
unsigned int sha1_data_problems = 1;
#endif

void lrad_hmac_sha1(const unsigned char *text, int text_len,
	                const unsigned char *key,  int key_len,
	                unsigned char *digest)
{
        SHA1_CTX context;
        unsigned char k_ipad[65];    /* inner padding -
                                      * key XORd with ipad
                                      */
        unsigned char k_opad[65];    /* outer padding -
                                      * key XORd with opad
                                      */
        unsigned char tk[20];
        int i;
        /* if key is longer than 64 bytes reset it to key=SHA1(key) */
        if (key_len > 64) {

                SHA1_CTX      tctx;

                SHA1Init(&tctx);
                SHA1Update(&tctx, key, key_len);
                SHA1Final(tk, &tctx);

                key = tk;
                key_len = 20;
        }

#ifdef HMAC_SHA1_DATA_PROBLEMS
	if(sha1_data_problems)
	{
		int j,k;

		printf("\nhmac-sha1 key(%d): ", key_len);
		j=0; k=0;
		for (i = 0; i < key_len; i++) {
			if(j==4) {
				printf("_");
				j=0;
			}
			j++;

			printf("%02x", key[i]);
		}
		printf("\nDATA: (%d)    ",text_len);

		j=0; k=0;
		for (i = 0; i < text_len; i++) {
		  if(k==20) {
		    printf("\n            ");
		    k=0;
		    j=0;
		  }
		  if(j==4) {
		    printf("_");
		    j=0;
		  }
		  k++;
		  j++;

		  printf("%02x", text[i]);
		}
		printf("\n");
	}
#endif


        /*
         * the HMAC_SHA1 transform looks like:
         *
         * SHA1(K XOR opad, SHA1(K XOR ipad, text))
         *
         * where K is an n byte key
         * ipad is the byte 0x36 repeated 64 times

         * opad is the byte 0x5c repeated 64 times
         * and text is the data being protected
         */

        /* start out by storing key in pads */
        memset( k_ipad, 0, sizeof(k_ipad));
        memset( k_opad, 0, sizeof(k_opad));
        memcpy( k_ipad, key, key_len);
        memcpy( k_opad, key, key_len);

        /* XOR key with ipad and opad values */
        for (i = 0; i < 64; i++) {
                k_ipad[i] ^= 0x36;
                k_opad[i] ^= 0x5c;
        }
        /*
         * perform inner SHA1
         */
        SHA1Init(&context);                   /* init context for 1st
                                              * pass */
        SHA1Update(&context, k_ipad, 64);      /* start with inner pad */
        SHA1Update(&context, text, text_len); /* then text of datagram */
        SHA1Final(digest, &context);          /* finish up 1st pass */
        /*
         * perform outer MD5
         */
        SHA1Init(&context);                   /* init context for 2nd
                                              * pass */
        SHA1Update(&context, k_opad, 64);     /* start with outer pad */
        SHA1Update(&context, digest, 20);     /* then results of 1st
                                              * hash */
        SHA1Final(digest, &context);          /* finish up 2nd pass */

#ifdef HMAC_SHA1_DATA_PROBLEMS
	if(sha1_data_problems)
	{
	  int j;

		printf("\nhmac-sha1 mac(20): ");
		j=0;
		for (i = 0; i < 20; i++) {
			if(j==4) {
				printf("_");
				j=0;
			}
			j++;

			printf("%02x", digest[i]);
		}
		printf("\n");
	}
#endif
}

/*
Test Vectors (Trailing '\0' of a character string not included in test):

  key =         "Jefe"
  data =        "what do ya want for nothing?"
  data_len =    28 bytes
  digest =

  key =         0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

  key_len       16 bytes
  data =        0xDDDDDDDDDDDDDDDDDDDD...
                ..DDDDDDDDDDDDDDDDDDDD...
                ..DDDDDDDDDDDDDDDDDDDD...
                ..DDDDDDDDDDDDDDDDDDDD...
                ..DDDDDDDDDDDDDDDDDDDD
  data_len =    50 bytes
  digest =      0x56be34521d144c88dbb8c733f0e8b3f6
*/
#ifdef TESTING
 /*
 *  cc -DTESTING -I ../include/ hmac.c md5.c -o hmac
 *
 *  ./hmac Jefe "what do ya want for nothing?"
 */

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
  unsigned char digest[20];
  char *key;
  int key_len;
  char *text;
  int text_len;
  int i;

  key = argv[1];
  key_len = strlen(key);

  text = argv[2];
  text_len = strlen(text);

  lrad_hmac_sha1(text, text_len, key, key_len, digest);

  for (i = 0; i < 20; i++) {
    printf("%02x", digest[i]);
  }
  printf("\n");

  exit(0);
  return 0;
}

#endif

	.file	"tmpxft_002ba67f_00000000-6_seq_hmac_sha1.cudafe1.cpp"
	.text
#APP

#NO_APP
	.type	_ZL26__cudaUnregisterBinaryUtilv, @function
_ZL26__cudaUnregisterBinaryUtilv:
.LFB2011:
	.cfi_startproc
	endbr64
	movq	_ZL20__cudaFatCubinHandle(%rip), %rdi
	jmp	__cudaUnregisterFatBinary@PLT
	.cfi_endproc
.LFE2011:
	.size	_ZL26__cudaUnregisterBinaryUtilv, .-_ZL26__cudaUnregisterBinaryUtilv
	.globl	_Z14lrad_hmac_sha1PKhiS0_iPh
	.type	_Z14lrad_hmac_sha1PKhiS0_iPh, @function
_Z14lrad_hmac_sha1PKhiS0_iPh:
.LFB2008:
	.cfi_startproc
	endbr64
	pushq	%r15
	.cfi_def_cfa_offset 16
	.cfi_offset 15, -16
	movl	%esi, %r15d
	pushq	%r14
	.cfi_def_cfa_offset 24
	.cfi_offset 14, -24
	movq	%rdi, %r14
	pushq	%r13
	.cfi_def_cfa_offset 32
	.cfi_offset 13, -32
	movq	%r8, %r13
	pushq	%r12
	.cfi_def_cfa_offset 40
	.cfi_offset 12, -40
	pushq	%rbp
	.cfi_def_cfa_offset 48
	.cfi_offset 6, -48
	pushq	%rbx
	.cfi_def_cfa_offset 56
	.cfi_offset 3, -56
	movq	%rdx, %rbx
	movslq	%ecx, %rdx
	subq	$280, %rsp
	.cfi_def_cfa_offset 336
	movq	%fs:40, %rax
	movq	%rax, 264(%rsp)
	xorl	%eax, %eax
	cmpl	$64, %edx
	jle	.L3
	leaq	20(%rsp), %rbp
	movl	%edx, 8(%rsp)
	movq	%rbp, %rdi
	call	_Z8SHA1InitP8SHA1_CTX@PLT
	movl	8(%rsp), %edx
	movq	%rbx, %rsi
	movq	%rbp, %rdi
	leaq	114(%rsp), %rbx
	call	_Z10SHA1UpdateP8SHA1_CTXPKhj@PLT
	movq	%rbp, %rsi
	movq	%rbx, %rdi
	call	_Z9SHA1FinalPhP8SHA1_CTX@PLT
	movl	$20, %edx
.L3:
	xorl	%eax, %eax
	movl	$65, %ecx
	movq	%rbx, %rsi
	movq	%rdx, 8(%rsp)
	leaq	134(%rsp), %r12
	leaq	199(%rsp), %rbp
	movq	%r12, %rdi
	rep stosb
	movl	$65, %ecx
	movq	%rbp, %rdi
	rep stosb
	movl	$65, %ecx
	movq	%r12, %rdi
	call	__memcpy_chk@PLT
	movq	8(%rsp), %rdx
	movq	%rbx, %rsi
	movq	%rbp, %rdi
	movl	$65, %ecx
	call	__memcpy_chk@PLT
	xorl	%eax, %eax
.L4:
	xorb	$54, (%r12,%rax)
	xorb	$92, 0(%rbp,%rax)
	incq	%rax
	cmpq	$64, %rax
	jne	.L4
	leaq	20(%rsp), %rbx
	movq	%rbx, %rdi
	call	_Z8SHA1InitP8SHA1_CTX@PLT
	movl	$64, %edx
	movq	%r12, %rsi
	movq	%rbx, %rdi
	call	_Z10SHA1UpdateP8SHA1_CTXPKhj@PLT
	movl	%r15d, %edx
	movq	%r14, %rsi
	movq	%rbx, %rdi
	call	_Z10SHA1UpdateP8SHA1_CTXPKhj@PLT
	movq	%rbx, %rsi
	movq	%r13, %rdi
	call	_Z9SHA1FinalPhP8SHA1_CTX@PLT
	movq	%rbx, %rdi
	call	_Z8SHA1InitP8SHA1_CTX@PLT
	movl	$64, %edx
	movq	%rbp, %rsi
	movq	%rbx, %rdi
	call	_Z10SHA1UpdateP8SHA1_CTXPKhj@PLT
	movq	%r13, %rsi
	movq	%rbx, %rdi
	movl	$20, %edx
	call	_Z10SHA1UpdateP8SHA1_CTXPKhj@PLT
	movq	%rbx, %rsi
	movq	%r13, %rdi
	call	_Z9SHA1FinalPhP8SHA1_CTX@PLT
	movq	264(%rsp), %rax
	subq	%fs:40, %rax
	je	.L5
	call	__stack_chk_fail@PLT
.L5:
	addq	$280, %rsp
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%rbp
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2008:
	.size	_Z14lrad_hmac_sha1PKhiS0_iPh, .-_Z14lrad_hmac_sha1PKhiS0_iPh
	.section	.text.startup,"ax",@progbits
	.type	_ZL24__sti____cudaRegisterAllv, @function
_ZL24__sti____cudaRegisterAllv:
.LFB2034:
	.cfi_startproc
	endbr64
	pushq	%rax
	.cfi_def_cfa_offset 16
	leaq	_ZL15__fatDeviceText(%rip), %rdi
	call	__cudaRegisterFatBinary@PLT
	movq	%rax, %rdi
	movq	%rax, _ZL20__cudaFatCubinHandle(%rip)
	call	__cudaRegisterFatBinaryEnd@PLT
	leaq	_ZL26__cudaUnregisterBinaryUtilv(%rip), %rdi
	popq	%rdx
	.cfi_def_cfa_offset 8
	jmp	atexit@PLT
	.cfi_endproc
.LFE2034:
	.size	_ZL24__sti____cudaRegisterAllv, .-_ZL24__sti____cudaRegisterAllv
	.section	.init_array,"aw"
	.align 8
	.quad	_ZL24__sti____cudaRegisterAllv
	.section	.nvFatBinSegment,"aw"
	.align 8
	.type	_ZL15__fatDeviceText, @object
	.size	_ZL15__fatDeviceText, 24
_ZL15__fatDeviceText:
	.long	1180844977
	.long	1
	.quad	fatbinData
	.quad	0
	.local	_ZL20__cudaFatCubinHandle
	.comm	_ZL20__cudaFatCubinHandle,8,8
	.ident	"GCC: (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"
	.section	.note.GNU-stack,"",@progbits
	.section	.note.gnu.property,"a"
	.align 8
	.long	1f - 0f
	.long	4f - 1f
	.long	5
0:
	.string	"GNU"
1:
	.align 8
	.long	0xc0000002
	.long	3f - 2f
2:
	.long	0x3
3:
	.align 8
4:

#ifndef _SEQ_HMAC_SHA1_H
#define _SEQ_HMAC_SHA1_H

void lrad_hmac_sha1(const unsigned char *text, int text_len, const unsigned char *key,  int key_len, unsigned char *digest);


#endif

	.text
	.file	"seq_hmac_sha1.hip"
	.type	__hip_cuid_,@object             # @__hip_cuid_
	.bss
	.globl	__hip_cuid_
__hip_cuid_:
	.byte	0                               # 0x0
	.size	__hip_cuid_, 1

	.ident	"AMD clang version 18.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-6.3.2 25012 e5bf7e55c91490b07c49d8960fa7983d864936c4)"
	.section	".note.GNU-stack","",@progbits
	.addrsig
	.addrsig_sym __hip_cuid_

	.text
	.p2alignl 7, 3214868480
	.fill 96, 4, 3214868480
	.type	__hip_cuid_,@object             ; @__hip_cuid_
	.section	.bss,"aw",@nobits
	.globl	__hip_cuid_
__hip_cuid_:
	.byte	0                               ; 0x0
	.size	__hip_cuid_, 1

	.ident	"AMD clang version 18.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-6.3.2 25012 e5bf7e55c91490b07c49d8960fa7983d864936c4)"
	.section	".note.GNU-stack","",@progbits
	.addrsig
	.addrsig_sym __hip_cuid_
	.amdgcn_target "amdgcn-amd-amdhsa--gfx1100"
	.amdgpu_metadata
---
amdhsa.kernels:  []
amdhsa.target:   amdgcn-amd-amdhsa--gfx1100
amdhsa.version:
  - 1
  - 2
...

	.end_amdgpu_metadata
