nx_hmac_workspace_adapter_t187.nx source
↩ module page · 31 lines · 1875 B
1import "nx_hmac.nx"
2// Caller-owned HMAC workspace. Sizes are SHA-256 block/digest widths, not
3// caller-content ceilings. All nested SHA operations borrow initialized storage.
4const HMAC_E_WORKSPACE:i64=0-2
5const HMAC_E_INPUT:i64=0-1
6func hmac_sha256_workspace_bytes()->i64{
7 return HMAC_BLOCK*2+HMAC_HASH+sha256_workspace_bytes()
8}
9func hmac_sha256_workspace(key:*u8,key_len:i64,msg:*u8,msg_len:i64,out:*u8,workspace:*u8,capacity:i64)->i64{
10 if sha256_checked_input(key,key_len,out)!=1 || sha256_checked_input(msg,msg_len,out)!=1{return HMAC_E_INPUT}
11 if msg_len>SHA256_SIGNED_MAX/SHA256_BITS_PER_BYTE-HMAC_BLOCK{return HMAC_E_INPUT}
12 let needed:i64=hmac_sha256_workspace_bytes();let base:i64=workspace as i64
13 if base<=0 || capacity<needed || base>SHA256_SIGNED_MAX-needed || base%SHA256_WORD_ALIGN!=0{return HMAC_E_WORKSPACE}
14 if sha256_ranges_overlap(base,needed,key as i64,key_len)==1 || sha256_ranges_overlap(base,needed,msg as i64,msg_len)==1 || sha256_ranges_overlap(base,needed,out as i64,HMAC_HASH)==1{return HMAC_E_WORKSPACE}
15 let kp:*u8=workspace;let pad:*u8=workspace+HMAC_BLOCK;let digest:*u8=pad+HMAC_BLOCK
16 let sw:*u8=digest+HMAC_HASH;let sn:i64=sha256_workspace_bytes()
17 var i:i64=0;while i<HMAC_BLOCK{kp[i]=0 as u8;i=i+1}
18 var rc:i64=0
19 if key_len>HMAC_BLOCK{rc=sha256_digest_workspace(key,key_len,kp,sw,sn)}
20 else{i=0;while i<key_len{kp[i]=key[i];i=i+1}}
21 if rc!=0{return rc}
22 i=0;while i<HMAC_BLOCK{pad[i]=kp[i]^IPAD;i=i+1}
23 rc=sha256_init_workspace(sw,sn);if rc!=0{return rc}
24 let ctx:*Sha256=sw as *Sha256
25 sha256_update(ctx,pad,HMAC_BLOCK);sha256_update(ctx,msg,msg_len);sha256_final(ctx,digest)
26 i=0;while i<HMAC_BLOCK{pad[i]=kp[i]^OPAD;i=i+1}
27 rc=sha256_init_workspace(sw,sn);if rc!=0{return rc}
28 sha256_update(ctx,pad,HMAC_BLOCK);sha256_update(ctx,digest,HMAC_HASH);sha256_final(ctx,out)
29 i=0;while i<needed{workspace[i]=0 as u8;i=i+1}
30 return 0
31}