cancel
Showing results for 
Search instead for 
Did you mean: 

I'm looking for a better way to make raw binary of signature & public key when I'm making a secure bootloader.

eziya76
Associate II

Hello,

When I'm learning "STM32 security in practice MOOC". I ran into the below scripts to make raw binary of signature and public key.

I thought it was not easy to use and explain to others.

Is there a better way to make a raw binary of signature and public key?

Thank you in advance.

PostBuild_sig.bat
 
ECHO ########## Convert signature from asn1 to raw binary ############  
IF EXIST temp.txt DEL temp.txt
FOR /F "tokens=4 delims=:" %%A IN ('%OPENSSL% asn1parse -in %tmp_sigfile% -inform=DER') DO >>temp.txt ECHO(%%A
CERTUTIL -f -decodehex temp.txt %tmp_sigfile% >nul
IF EXIST temp.txt DEL temp.txt
	ECHO FW Signature
	%HEXDUMP% %tmp_sigfile%
	
ECHO "################# Generate public key from private ecc key "
%OPENSSL% pkey -in ecc.key -pubout -out ecc_pub.key 
ECHO "################# Convert public key to binary "
%OPENSSL% ec -pubin -in ecc_pub.key -text -noout |%GREP% ":"|%GREP% "    "|%SED% 's/    /-/g'|%SED% 's/:/,:/g'|%AWK% -F ":" "{ print $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15}"|%SED% 's/-04,//'|%SED% 's/  //g' >> temp.txt 
CERTUTIL -f -decodehex temp.txt %tmp_keypub% >nul
IF EXIST temp.txt DEL temp.txt
	ECHO Public Key
	%HEXDUMP% %tmp_keypub%

6 REPLIES 6
Pavel A.
Evangelist III

You are right. The Windows/DOS bat files are horrible abomination from the past century.

CubeIDE for Windows comes with a decent posix shell and GNU utilities. They just should convert all this cruft.

eziya76
Associate II

I wrote some pre-build & post-build scripts for myself.

I thought that the PowerShell script might be easier to use and understand than the batch script.

As these are my first PowerShell script, there could be lots of points to improve.

I hope these might help someone who needs the same things as I did.

<prebuild.ps1>

# file location
$HEADER_FILE = "..\Core\Inc\ecc_pub_key.h"
$ECC_PARAM = ".\ecc_param.key"
$ECC_PRIK = ".\ecc.key"
$ECC_PUBK = ".\ecc_pub.key"
$OPENSSL = ".\openssl.exe"
 
#STEP1. Generate Public Key
Write-Host "`r`nSTEP1. ECC key generation..."
 
Write-Host "$OPENSSL ecparam -name prime256v1 -genkey -out $ECC_PARAM"
#Invoke-Expression "$OPENSSL ecparam -name prime256v1 -genkey -out $ECC_PARAM"
 
Write-Host "$OPENSSL ecparam -in $ECC_PARAM -genkey -out $ECC_PRIK"
#Invoke-Expression "$OPENSSL ecparam -in $ECC_PARAM -genkey -out $ECC_PRIK"
 
Write-Host "$OPENSSL pkey -in $ECC_PRIK -pubout -out $ECC_PUBK"
#Invoke-Expression "$OPENSSL pkey -in $ECC_PRIK -pubout -out $ECC_PUBK"
 
#STEP2. Read Pubic Key
Write-Host "`r`nSTEP2. Read Pubic Key"
Write-Host "$OPENSSL ec -pubin -in $ECC_PUBK -text -noout | Select -Index @(2,3,4,5,6)"
$ErrorActionPreference = 'SilentlyContinue'
$pubKStr = Invoke-Expression "$OPENSSL ec -pubin -in $ECC_PUBK -text -noout | Select -Index @(2,3,4,5,6)"
$pubKstr
$ErrorActionPreference = 'Continue'
 
#STEP3. Create Header File
Write-Host "`r`nSTEP3. Create Header File"
 
$pubKStr = $pubKStr -replace '\s', ''
$pubKStr = $pubKStr -replace ':', ',0x'
 
$pubKStrLine1 = $pubKStr | Select -Index 0
$pubKStrLine2 = "0x" + ($pubKStr | Select -Index 1)
$pubKStrLine3 = "0x" + ($pubKStr | Select -Index 2)
$pubKStrLine4 = "0x" + ($pubKStr | Select -Index 3)
$pubKStrLine5 = "0x" + ($pubKStr | Select -Index 4)
 
$pubKStrLine1 = $pubKStrLine1.Substring(3, $pubKStrLine1.Length-5 )
$pubKStrLine2 = $pubKStrLine2.Substring(0, $pubKStrLine2.Length-2 )
$pubKStrLine3 = $pubKStrLine3.Substring(0, $pubKStrLine3.Length-2 )
$pubKStrLine4 = $pubKStrLine4.Substring(0, $pubKStrLine4.Length-2 )
 
$HeaderStr =
"#ifndef __ECC_PUB_KEY_H_
#define __ECC_PUB_KEY_H_
static uint8_t SIGN_ECC_PUB_KEY[] = {
`t$pubKStrLine1
`t$pubKStrLine2
`t$pubKStrLine3
`t$pubKStrLine4
`t$pubKStrLine5
};
#endif /*__ECC_PUB_KEY_H_*/"
 
$HeaderStr = $HeaderStr -replace '`n', '`r`n'
 
Write-Host $HeaderStr
$HeaderStr | Out-File -Encoding utf8 -FilePath $HEADER_FILE

eziya76
Associate II

< Post build.ps1> 

# file location
$BIN_ORIGIN = "..\Debug\STM32_HAL_APP_AUTHENTICATION.bin"
$BIN_PAD = "..\Debug\STM32_HAL_APP_AUTHENTICATION_PAD.bin"
$BIN_PAD_HASH_SIG_PUBK = '..\Debug\STM32_HAL_APP_AUTHENTICATION_PAD_HASH_SIG_PUBK.bin'
 
$TEMP_HASH = "..\Debug\TempHash.sha"
$TEMP_PUBK = "..\Debug\TempPubK.pub"
$TEMP_PUBKTXT = "..\Debug\TempPubK.txt"
$TEMP_SIG = "..\Debug\TempSig.sig"
$TEMP_SIGTXT = "..\Debug\RawSig.txt"
 
$ECC_PRIK = ".\ecc.key"
$ECC_PUBK = ".\ecc_pub.key"
 
$OPENSSL = ".\openssl.exe"
$SREC = ".\srec_cat.exe"
$HEXDUMP =".\hexdump.exe"
$CERTUTL = "certutil"
 
# padding related variables
$padding = 0x00
$pageSize = 2048
$binSize = (Get-Item $BIN_ORIGIN).Length
$padBinSize = $pageSize - ($binSize % $pageSize) + $binSize
 
 
# STEP1. Padding
Write-Host "`r`nSTEP1. Padding..."
Write-Host "Padding Format:$padding"
Write-Host "Page Size:$pageSize"
Write-Host "Bin File Size:$binSize"
Write-Host "Padded File Size:$padBinSize"
 
Write-Host "$SREC $BIN_ORIGIN -binary -fill $padding 0x0000 $padBinSize -o $BIN_PAD -binary"
Invoke-Expression "$SREC $BIN_ORIGIN -binary -fill $padding 0x0000 $padBinSize -o $BIN_PAD -binary"
 
# STEP2. Hasing
Write-Host "`r`nSTEP2. Hashing..."
 
Write-Host "$OPENSSL dgst -sha256 -binary -out $TEMP_HASH $BIN_PAD"
Invoke-Expression "$OPENSSL dgst -sha256 -binary -out $TEMP_HASH $BIN_PAD"
Invoke-Expression "$HEXDUMP $TEMP_HASH"
 
# STEP3. Signing
Write-Host "`r`nSTEP3. Signing..."
 
Write-Host "$OPENSSL pkeyutl -sign -pkeyopt digest:sha256 -inkey $ECC_PRIK -in $TEMP_HASH -out $TEMP_SIG"
Invoke-Expression "$OPENSSL pkeyutl -sign -pkeyopt digest:sha256 -inkey $ECC_PRIK -in $TEMP_HASH -out $TEMP_SIG"
 
#STEP4. Convert signature fomat(ASN1 to raw binary)
Write-Host "`r`nSTEP4. Converting signature format(ASN1 to raw binary)"
 
Write-Host "$OPENSSL asn1parse -in $TEMP_SIG -inform=DER"
Invoke-Expression "$OPENSSL asn1parse -in $TEMP_SIG -inform=DER"
 
$prime1Str = (Invoke-Expression "$OPENSSL asn1parse -in $TEMP_SIG -inform=DER | Select -Index 1")
$prime2Str = (Invoke-Expression "$OPENSSL asn1parse -in $TEMP_SIG -inform=DER | Select -Index 2")
 
$prime1Idx = ($prime1Str | Select-String -Pattern ':' -AllMatches).Matches.Index[2]
$prime2Idx = ($prime2Str | Select-String -Pattern ':' -AllMatches).Matches.Index[2]
 
$prime1 = $prime1Str.Substring([int]$prime1Idx+1)
$prime2 = $prime2Str.Substring([int]$prime2Idx+1)
 
$prime1+$prime2 | Out-File -FilePath $TEMP_SIGTXT
Invoke-Expression "$CERTUTL -f -decodehex $TEMP_SIGTXT $TEMP_SIG"
Invoke-Expression "$HEXDUMP $TEMP_SIG"
 
#STEP5. Convert public key to binary
Write-Host "`r`nSTEP5. Converting public key to binary"
 
$ErrorActionPreference = 'SilentlyContinue'
Write-Host "$OPENSSL ec -pubin -in $ECC_PUBK -text -noout | Select -Index @(2,3,4,5,6)"
 
$pubKStr = Invoke-Expression "$OPENSSL ec -pubin -in $ECC_PUBK -text -noout | Select -Index @(2,3,4,5,6)"
$pubKstr
$ErrorActionPreference = 'Continue'
 
$pubKStr = $pubKStr -join ''
$pubKStr = $pubKStr -replace '\s', ''
$pubKStr = $pubKStr -replace ':', ''
$pubKStr = $pubKStr.Substring(2)
Write-Host $pubKStr
 
$pubKStr | Out-File -FilePath $TEMP_PUBKTXT
Invoke-Expression "$CERTUTL -f -decodehex $TEMP_PUBKTXT $TEMP_PUBK"
Invoke-Expression "$HEXDUMP $TEMP_PUBK"
 
#STEP6. Append hash,signature,public key to padded binary
Write-Host "`r`nSTEP6. Append hash,signature,public key to padded binary"
Write-Host "Get-Content $BIN_PAD, $TEMP_HASH, $TEMP_SIG, $TEMP_PUBK -Encoding Byte | Set-Content $BIN_PAD_HASH_SIG_PUBK -Encoding Byte"
 
Get-Content $BIN_PAD, $TEMP_HASH, $TEMP_SIG, $TEMP_PUBK -Encoding Byte | Set-Content $BIN_PAD_HASH_SIG_PUBK -Encoding Byte
 
Write-Host "BIN_ORIGIN length:" (Get-Item $BIN_ORIGIN).Length
Write-Host "BIN_PAD length:" (Get-Item $BIN_PAD).Length
Write-Host "TEMP_HASH length:" (Get-Item $TEMP_HASH).Length
Write-Host "TEMP_SIG length:" (Get-Item $TEMP_SIG).Length
Write-Host "TEMP_PUBK length:" (Get-Item $TEMP_PUBK).Length
Write-Host "BIN_PAD_HASH_SIG_PUBK length:" (Get-Item $BIN_PAD_HASH_SIG_PUBK).Length

Powershell is another horrible abomination.

Piranha
Chief II

Making a simple command line application in C with uECC and BearSSL is really simple and can be extended to anything. And yes - uECC uses raw binary keys.

uECC & BearSSL looks interesting.. As you said. I could be simpler with those tools.

Thank you Piranha.