Deriving key and vector for AES-256

Just starting out? Need help? Post your questions and find answers here.
User avatar
Catdaddy
User
User
Posts: 30
Joined: Wed Mar 23, 2022 3:40 pm

Deriving key and vector for AES-256

Post by Catdaddy »

Hello,

I am attempting to use AESEncryption in Purebasic. I want to be able to encrypt/decrypt strings with AES-256. I am using #PB_Cipher_CBC so I need to have a 32bit key and 16bit vector. In my code I am deriving the key and vector bytes from the fingerprint (SHA3) of a given string. I chop up the first 64 bytes of the fingerprint into 32 pairs of Hex strings which the value of are poked into a memory buffer to be read as the Key. Likewise, the last 32 bytes of the fingerprint are chopped up into 16 pairs of Hex strings which the value of each are poked into a memory buffer to be read as the Vector.

If you run my code you'll see that the bytes that are poked into the memory buffers (for the key and vector) are not what is being peeked from each buffer. When I point AESEncoder to the key and vector buffers I don't believe the values are correct.

Not sure if I'm explaining this correctly but if anyone could lend a hand I would be extremely grateful. Thank you.

Code: Select all

UseSHA3Fingerprint()

Procedure DeriveKey(Password.s, *Key, *InitVect)
	Fingerprint.s = StringFingerprint(Password, #PB_Cipher_SHA3, 512)

	Key.s = Left(Fingerprint, 64)
	InitVect.s = Right(Fingerprint, 32)

	Debug "FingerPrint: " + Fingerprint
	Debug "Key String: " + Key
	Debug "Vect String: " + InitVect		

	;Key
	Counter.b = 0
	Debug ""
	Debug "Key"
	Debug "==="
	For C = 1 To 64 Step 2
		ByteString.s = "$" + Mid(Key, C, 2)
		Debug ByteString + " = " + Val(ByteString)
		PokeB(*Key + Counter, Val(ByteString))
		Counter+1
	Next

	;InitVect
	Counter.b = 0
	Debug ""
	Debug "InitVect"
	Debug "========"
	For C = 1 To 32 Step 2
		ByteString.s = "$" + Mid(InitVect, C, 2)
		Debug ByteString + " = " + Val(ByteString)
		PokeB(*InitVect + Counter, Val(ByteString))
		Counter+1
	Next
EndProcedure


*Key = AllocateMemory(32)
*InitVect = AllocateMemory(16)

DeriveKey("iamjustarandomstring", *Key, *InitVect)

Debug ""
Debug "Peeked key"
Debug "========"
 
For C = 0 To 31
	Debug PeekB(*Key + C)
Next


Debug ""
Debug "Peeked vect"
Debug "========"
 
For C = 0 To 15
	Debug PeekB(*InitVect + C)
Next
User avatar
spikey
Enthusiast
Enthusiast
Posts: 778
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: Deriving key and vector for AES-256

Post by spikey »

You are overflowing the byte type numeric limit. It's a signed type and supports values between -128 and +127. Anything larger than +127 poked into a memory address will be interpreted as a negative when read back with PeekB because it has the sign bit set. If you read back with PeekA it should look more like what you're expecting to see (because the A type is unsigned).
User avatar
Mijikai
Addict
Addict
Posts: 1520
Joined: Sun Sep 11, 2016 2:17 pm

Re: Deriving key and vector for AES-256

Post by Mijikai »

Like this ?

Code: Select all

EnableExplicit

UseSHA3Fingerprint()

Procedure.i DeriveKey(Password.s)
  Protected *key
  Protected sha.s
  *key = AllocateMemory(48)
  If *key
    sha = StringFingerprint(Password,#PB_Cipher_SHA3,512)
    CopyMemory(@sha,*key,32)
    CopyMemory(@sha + StringByteLength(sha) - 16,*key + 32,16)
    Debug sha
  EndIf
  ProcedureReturn *key
EndProcedure

Procedure.i Main()
  Protected *key
  Protected *vec
  *key = DeriveKey("iamjustarandomstring")
  *vec = *key + 32
  Debug PeekS(*key,16)
  Debug PeekS(*vec,8)
  ProcedureReturn #Null
EndProcedure

End Main()
User avatar
Catdaddy
User
User
Posts: 30
Joined: Wed Mar 23, 2022 3:40 pm

Re: Deriving key and vector for AES-256

Post by Catdaddy »

spikey wrote: Mon Dec 18, 2023 7:13 pm You are overflowing the byte type numeric limit. It's a signed type and supports values between -128 and +127. Anything larger than +127 poked into a memory address will be interpreted as a negative when read back with PeekB because it has the sign bit set. If you read back with PeekA it should look more like what you're expecting to see (because the A type is unsigned).
:oops: You are absolutely correct. Forgive me, I'm still getting used to PureBasic types. Still got a ways to go :)
User avatar
Catdaddy
User
User
Posts: 30
Joined: Wed Mar 23, 2022 3:40 pm

Re: Deriving key and vector for AES-256

Post by Catdaddy »

Mijikai wrote: Mon Dec 18, 2023 7:22 pm Like this ?

Code: Select all

EnableExplicit

UseSHA3Fingerprint()

Procedure.i DeriveKey(Password.s)
  Protected *key
  Protected sha.s
  *key = AllocateMemory(48)
  If *key
    sha = StringFingerprint(Password,#PB_Cipher_SHA3,512)
    CopyMemory(@sha,*key,32)
    CopyMemory(@sha + StringByteLength(sha) - 16,*key + 32,16)
    Debug sha
  EndIf
  ProcedureReturn *key
EndProcedure

Procedure.i Main()
  Protected *key
  Protected *vec
  *key = DeriveKey("iamjustarandomstring")
  *vec = *key + 32
  Debug PeekS(*key,16)
  Debug PeekS(*vec,8)
  ProcedureReturn #Null
EndProcedure

End Main()
This is MUCH more elegant than my code. Thank you, Mijikai. You can probably tell I'm just getting my feet wet with pointers and working directly with memory.
User avatar
Catdaddy
User
User
Posts: 30
Joined: Wed Mar 23, 2022 3:40 pm

Re: Deriving key and vector for AES-256

Post by Catdaddy »

OK. Forgive me for being a pain, but how can I expose a pointer to a procedure? I slightly modified the example listing for AESEncoder() (see below). Whenever I run this I get a specified buffer is 0 error. I thought "Shared" gave the procedure access to the variable (*Key and *Vec). Does this not work with pointers? Sorry for being dense.

Code: Select all

UseSHA3Fingerprint()

Procedure.s CryptString(String.s, Action.i)
	Shared *Key
	Shared *Vec

	StringMemorySize = StringByteLength(String) + SizeOf(Character)
	*CipheredString = AllocateMemory(StringMemorySize)   
	*DecipheredString = AllocateMemory(StringMemorySize) 
	
	If Action = 1
		AESEncoder(@String$, *CipheredString, StringByteLength(String), *Key, 256, *Vec)
		ProcedureReturn PeekS(*CipheredString)
	EndIf

	If Action = 0
		AESDecoder(*CipheredString, *DecipheredString, StringByteLength(String), *Key, 256, *Vec)
		ProcedureReturn PeekS(*DecipheredString)
	EndIf
EndProcedure

*Key = AllocateMemory(64)
*Vec = AllocateMemory(32)
Password.s = "iamjustarandomstring"
Fingerprint.s = StringFingerprint(Password, #PB_Cipher_SHA3, 512)
CopyMemory(@Fingerprint,*Key,64)
CopyMemory(@Fingerprint + StringByteLength(Fingerprint) - 64,*Vec,32)

Debug "Key: " + PeekS(*Key,32)
Debug "Vector: " + PeekS(*Vec,16)

Debug CryptString("password", 1)
User avatar
spikey
Enthusiast
Enthusiast
Posts: 778
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: Deriving key and vector for AES-256

Post by spikey »

String$ <> String.s, see line 12. These are two separate variables in PB.

I'd strongly advise the use of the EnableExplicit directive which will trap this sort of typo.
User avatar
Catdaddy
User
User
Posts: 30
Joined: Wed Mar 23, 2022 3:40 pm

Re: Deriving key and vector for AES-256

Post by Catdaddy »

spikey wrote: Tue Dec 19, 2023 5:01 pm String$ <> String.s, see line 12. These are two separate variables in PB.

I'd strongly advise the use of the EnableExplicit directive which will trap this sort of typo.
Thank you, Spikey. That's what I get for being in a rush. Happy Holidays!
User avatar
spikey
Enthusiast
Enthusiast
Posts: 778
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: Deriving key and vector for AES-256

Post by spikey »

Catdaddy wrote: Tue Dec 19, 2023 5:30 pm Happy Holidays!
And to you! :D
freak
PureBasic Team
PureBasic Team
Posts: 5948
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Deriving key and vector for AES-256

Post by freak »

The DeriveCypherKey() function in the new 6.10 beta release is designed for this. An example can be found here: https://www.purebasic.fr/english/viewto ... 71#p613171
quidquid Latine dictum sit altum videtur
User avatar
Catdaddy
User
User
Posts: 30
Joined: Wed Mar 23, 2022 3:40 pm

Re: Deriving key and vector for AES-256

Post by Catdaddy »

freak wrote: Sat Dec 23, 2023 2:45 pm The DeriveCypherKey() function in the new 6.10 beta release is designed for this. An example can be found here: https://www.purebasic.fr/english/viewto ... 71#p613171
Whoa!!! Christmas came early this year :D Thank you, Freak. I'm definitely going to try the beta. Merry Christmas!
Post Reply