Skip to content
Snippets Groups Projects
Commit 0ae7c954 authored by Yossi Mansharoff's avatar Yossi Mansharoff Committed by Nico Dechesne (Stage)
Browse files

LK simple sign tool to work in non secure boot

Imported in git from

https://source.codeaurora.org/patches/quic/imm/PATCH_1694964_410c_signlk.tar.gz



Signed-off-by: default avatarYossi Mansharoff <yossim@codeaurora.org>
Change-Id: Ia8823b78c4d9bbe901e6807d4ff03a29c1e496db
Signed-off-by: default avatarNicolas Dechesne <nicolas.dechesne@linaro.org>
parents
No related branches found
No related tags found
No related merge requests found
LICENSE 0 → 100755
Copyright (c) 2016, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
CXX=g++
cur-dir := $(mfile_path)
ELFIODIR=${cur-dir}/ELFIO/elfio/
SOURCES=${cur-dir}/signlk.cpp
CPPFLAGS=-c -Wall -std=c++0x -I$(cur-dir)/ELFIO/
INCLUDES=$(ELFIODIR)elfio.hpp $(ELFIODIR)elfio_header.hpp \
$(ELFIODIR)elfio_note.hpp $(ELFIODIR)elfio_section.hpp \
$(ELFIODIR)elfio_segment.hpp $(ELFIODIR)elfio_strings.hpp \
$(ELFIODIR)elfio_symbols.hpp $(ELFIODIR)elfio_utils.hpp \
$(ELFIODIR)elf_types.hpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=${cur-dir}/signlk
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CXX) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CXX) $(CPPFLAGS) $< -o $@
test: $(EXECUTABLE)
./$(EXECUTABLE)
clean:
rm $(OBJECTS) $(EXECUTABLE)
/******************************************************************************/
/* Copyright (c) 2016, The Linux Foundation. All rights reserved. */
/* */
/* Redistribution and use in source and binary forms, with or without */
/* modification, are permitted provided that the following conditions are */
/* met: */
/* * Redistributions of source code must retain the above copyright */
/* notice, this list of conditions and the following disclaimer. */
/* * Redistributions in binary form must reproduce the above */
/* copyright notice, this list of conditions and the following */
/* disclaimer in the documentation and/or other materials provided */
/* with the distribution. */
/* * Neither the name of The Linux Foundation nor the names of its */
/* contributors may be used to endorse or promote products derived */
/* from this software without specific prior written permission. */
/* */
/* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED */
/* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT */
/* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS */
/* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR */
/* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */
/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */
/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, */
/* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE */
/* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN */
/* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/******************************************************************************/
#include <iostream>
#include <elfio/elfio.hpp>
using namespace ELFIO;
/* struct to store hash segment header */
typedef struct
{
unsigned int header_vsn_num; /* Header version number. */
unsigned int image_id; /* Identifies the type of image this header */
unsigned int image_src; /* Location of image in flash */
unsigned int image_dest_ptr; /* Pointer to location to store image in RAM. */
unsigned int image_size; /* Size of complete image in bytes */
unsigned int code_size; /* Size of code region of image in bytes */
unsigned int signature_ptr; /* Pointer to images attestation signature */
unsigned int signature_size; /* Size of the attestation signature in bytes */
unsigned int cert_chain_ptr; /* Pointer to the chain of attestation
certificates associated with the image. */
unsigned int cert_chain_size; /* Size of the attestation chain in bytes */
} mi_boot_image_header_type;
#define HASH_CODE_SIZE 0x80
#define SIGNATURE_SIZE 0x100
#define CERT_CHAIN_SIZE 0x1800
#define MAX_CERT_CHAIN_SIZE 0x2000
#define SHT_QC 0x70000003
#define SHT_EXIDX 0x70000001
#define HASH_SE_ALIGN 0x1000
#define HASH_SE_FLAG 0x2200000
int readSecurityDataFromFile(char *buff, std::string root_cert_file_name, std::string atte_cert_file_name)
{
std::ifstream stream;
// Read ELF file signature
stream.open( atte_cert_file_name, std::ios::in | std::ios::binary );
if ( !stream ) {
std::cout << "cant open attestation certificate file"<< atte_cert_file_name << std::endl;
return 1;
}
// Read ELF file signature
stream.seekg( 0 );
int atte_cert_size=0;
for (atte_cert_size = HASH_CODE_SIZE+SIGNATURE_SIZE+sizeof(mi_boot_image_header_type); atte_cert_size < MAX_CERT_CHAIN_SIZE ; atte_cert_size++)
{
if(stream.eof()) break;
stream.read(&buff[atte_cert_size],1);
if(stream.eof()) break;
}
stream.close();
stream.open( root_cert_file_name, std::ios::in | std::ios::binary );
if ( !stream ) {
std::cout << "cant open root certificate file"<< root_cert_file_name << std::endl;
return 1;
}
stream.seekg( 0 );
for (; atte_cert_size < MAX_CERT_CHAIN_SIZE ; atte_cert_size++)
{
if(stream.eof()) break;
stream.read(&buff[atte_cert_size],1);
if(stream.eof()) break;
}
stream.close();
for (int i=atte_cert_size; i < MAX_CERT_CHAIN_SIZE ; i++)
{
buff[i] = 0xff;
}
return 0;
}
int main( int argc, char** argv )
{
if ( argc != 5 ) {
std::cout << "Usage: signlk <unsigned_elf_file> <signed_elf_file> <root_certificate_file> <attestation_CA_certificate_file>" << std::endl;
return 1;
}
// Create an elfio reader and writer
elfio reader;
elfio writer;
char cert_chain[MAX_CERT_CHAIN_SIZE]={0};
unsigned int hash_segment_address = 0;
std::string root_cert_file_name=(std::string )argv[3];
std::string atte_cert_file_name=(std::string )argv[4];
section* data_sec;
Elf_Word maxAddress = 0;
section* maxSec = NULL;
section* mi_sec = NULL;
segment* header_seg = NULL;
segment* hash_seg = NULL;
Elf_Half sec_num;
Elf_Half seg_num;
Elf_Half headerSize;
mi_boot_image_header_type mi={0};
/* create a write configuration */
writer.create( ELFCLASS32, ELFDATA2LSB );
writer.set_os_abi( ELFOSABI_NONE );
writer.set_type( ET_EXEC );
writer.set_machine( EM_ARM );
writer.set_flags(0x5000002);
// Load ELF data
if ( !reader.load( argv[1] ) ) {
std::cout << "Can't find or process ELF file " << argv[1] << std::endl;
return 2;
}
sec_num = reader.sections.size();
seg_num = reader.segments.size();
std::cout << "using attestation certificate file: "<< atte_cert_file_name << std::endl
<<"root certificate file: "<< root_cert_file_name << std::endl
<<"input file: "<<argv[1]<<std::endl
<<"output file: "<<argv[2]<<std::endl;
/* create new segments for header and hash */
header_seg = writer.segments.add();
hash_seg = writer.segments.add();
/* copy the original elf segments to the signed elf */
for ( int i = 0; i < seg_num; ++i ) {
const segment* pseg = reader.segments[i];
segment* data_seg = writer.segments.add();
data_seg->set_type( pseg->get_type() );
data_seg->set_virtual_address( pseg->get_virtual_address() );
data_seg->set_physical_address( pseg->get_physical_address() );
data_seg->set_flags( pseg->get_flags() );
data_seg->set_align( pseg->get_align() );
data_seg->set_file_size(pseg->get_file_size());
data_seg->set_memory_size(pseg->get_memory_size());
}
/* copy loadable sections to target file*/
for ( int i = 0; i < sec_num; ++i ) {
section* psec = reader.sections[i];
/* copy only loadable sections */
if ((psec->get_type()==SHT_PROGBITS)
||(psec->get_type()==SHT_HASH)
||(psec->get_type()==SHT_EXIDX))
{
data_sec = writer.sections.add(psec->get_name());
data_sec->set_type( psec->get_type() );
data_sec->set_flags( psec->get_flags() );
data_sec->set_addr_align( psec->get_addr_align() );
data_sec->set_data( psec->get_data(), psec->get_size() );
writer.segments[writer.segments.size() - 1]->add_section_index( data_sec->get_index(), data_sec->get_addr_align() );
}
}
/* Create data section*/
headerSize = writer.get_header_size() +(writer.segments.size())*32;
data_sec = writer.sections.add( "" );
data_sec->set_type( SHT_NULL );
data_sec->set_flags( SHF_ALLOC );
data_sec->set_addr_align( 0 );
char data[0x100]={0};
data_sec->set_data( data, headerSize );
/* Create a read/write segment */
header_seg->set_type( PT_NULL );
header_seg->set_virtual_address( 0 );
header_seg->set_physical_address( 0 );
header_seg->set_flags( 0 );
header_seg->set_align( 4 );
header_seg->set_memory_size(headerSize);
// Add code section into program segment
header_seg->add_section_index( data_sec->get_index(), data_sec->get_addr_align() );
/* scan for the elf file section max address to insert the hash section */
for ( int i = 0; i < sec_num; ++i ) {
section* psec = reader.sections[i];
/* copy only loadable sections */
if ((psec->get_type()==SHT_PROGBITS)
||(psec->get_type()==SHT_HASH)
||(psec->get_type()==SHT_EXIDX))
{
/* store max section address for hash section */
if (psec->get_address() > maxAddress)
{
maxAddress = psec->get_address();
maxSec = psec;
}
}
}
/* calculate section address */
hash_segment_address = (maxSec->get_address() + (maxSec->get_addr_align() - (maxSec->get_address() % maxSec->get_addr_align())));
hash_segment_address = (hash_segment_address + (HASH_SE_ALIGN - (hash_segment_address % HASH_SE_ALIGN)));
/* read the certificates from input files */
if (readSecurityDataFromFile(cert_chain, root_cert_file_name, atte_cert_file_name))
{
std::cout << "exiting" << std::endl;
return 1;
}
/* set the hash segment header data */
mi.image_id = 0x3;
mi.image_dest_ptr = hash_segment_address + sizeof(mi_boot_image_header_type);
mi.code_size = HASH_CODE_SIZE;
mi.header_vsn_num = 0;
mi.signature_ptr = mi.image_dest_ptr + mi.code_size;
mi.signature_size =SIGNATURE_SIZE;
mi.cert_chain_ptr = mi.signature_ptr + mi.signature_size;
mi.cert_chain_size = CERT_CHAIN_SIZE;
mi.image_size = mi.cert_chain_size + mi.signature_size + mi.code_size;
memcpy(cert_chain,&mi,sizeof(mi));
/* create section */
mi_sec = writer.sections.add( ".mi" );
mi_sec->set_type( PT_LOPROC );
mi_sec->set_flags( SHF_ALLOC );
mi_sec->set_addr_align( HASH_SE_ALIGN );
mi_sec->set_data( cert_chain, sizeof( cert_chain ) );
// Create a read/write segment
hash_seg->set_type( PT_LOPROC);
hash_seg->set_virtual_address( hash_segment_address );
hash_seg->set_physical_address( hash_segment_address);
hash_seg->set_flags( HASH_SE_FLAG );
hash_seg->set_align( HASH_SE_ALIGN );
hash_seg->set_file_size(mi.image_size);
hash_seg->set_memory_size(MAX_CERT_CHAIN_SIZE);
/* Add code section into program segment */
hash_seg->add_section_index( mi_sec->get_index(), mi_sec->get_addr_align() );
/* set the entry point */
writer.set_entry(reader.get_entry());
/* Create ELF file */
writer.save(argv[2]);
return 0;
}
signlk.sh 0 → 100755
################################################################################
# Copyright (c) 2016, The Linux Foundation. All rights reserved. #
# #
# Redistribution and use in source and binary forms, with or without #
# modification, are permitted provided that the following conditions are #
# met: #
# * Redistributions of source code must retain the above copyright #
# notice, this list of conditions and the following disclaimer. #
# * Redistributions in binary form must reproduce the above #
# copyright notice, this list of conditions and the following #
# disclaimer in the documentation and/or other materials provided #
# with the distribution. #
# * Neither the name of The Linux Foundation nor the names of its #
# contributors may be used to endorse or promote products derived #
# from this software without specific prior written permission. #
# #
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED #
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT #
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS #
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR #
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF #
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR #
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, #
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE #
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN #
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #
# #
# THIS IS A WORKAROUND TO GET LK INTO THE PROPER FORMAT, #
# NO SECURITY IS BEING PROVIDED BY THE OPENSSL CALLS HAPPENING UNDER THE HOOD #
################################################################################
INFILE=""
OUTFILE=""
DIR=$(dirname $0)
EXECUTABLE="$DIR/signer/signlk"
CN=""
OU=""
for i in "$@"
do
case $i in
-i=*|--in=*)
INFILE="${i#*=}"
;;
-o=*|--out=*)
OUTFILE="${i#*=}"
;;
-OU=*|-ou=*)
OU="${i#*=}"
;;
-CN=*|-cn=*)
CN="${i#*=}"
;;
-h*|--help*)
echo "signlk -i=input_file_name [-o=output_file_name]"
echo "-i input ELF/MBN file name"
echo "-o output file name, input_file_name with suffix of 'signed' as default "
exit 0
;;
*)
echo "unsupported option" # unknown option
echo "type signlk --help for help"
exit 1
;;
esac
done
if [ "$INFILE" == "" ]; then
echo "signlk -i=input_file_name [-o=output_file_name]"
exit 2
fi
INFILE_filename=$(echo $INFILE | rev | cut -f 2- -d '.' | rev)
INFILE_extension=$(echo $INFILE | rev | cut -f 1 -d '.' | rev)
if [ "$INFILE_extension" == "" ]; then
echo "input file must be an elf or mbn file"
exit 3
fi
if [ "$INFILE_extension" != "elf" ] && [ "$INFILE_extension" != "mbn" ] && [ "$INFILE_extension" != "ELF" ] && [ "$INFILE_extension" != "MBN" ]; then
echo "input file must be an elf or mbn file"
exit 4
fi
if [ "$OUTFILE" == "" ]; then
OUTFILE=$INFILE_filename"_signed.mbn"
fi
echo "generating output file $OUTFILE"
if [ ! -f "$EXECUTABLE" ]; then
echo "building executable..."
export mfile_path=$DIR/signer
make -f $mfile_path/Makefile
if [ "$?" != 0 ]; then
echo " failed to build executable"
exit 5
fi
fi
tmp=$(mktemp -d)
tmp_att_file=$tmp/e.ext
echo "authorityKeyIdentifier=keyid,issuer" >> $tmp_att_file
echo "basicConstraints=CA:FALSE,pathlen:0" >> $tmp_att_file
echo "keyUsage=digitalSignature" >> $tmp_att_file
if [ ! "$(openssl version)" ]; then
echo "please install openssl"
exit 6
fi
if [ ! "$(make -v)" ]; then
echo "please install gcc"
exit 7
fi
if [ ! "$(g++ --version)" ]; then
echo "please install g++"
exit 8
fi
openssl req -new -x509 -keyout $tmp/root_key.PEM -nodes -newkey rsa:2048 -days 7300 -set_serial 1 -sha256 -subj "/CN=$CN/O=$OU/C=/CN=DRAGONBOARD TEST PKI – NOT SECURE/L=/O=S/ST=/OU=01 0000000000000009 SW_ID/OU=02 0000000000000000 HW_ID" > $tmp/root_certificate.PEM 2>/dev/null
openssl x509 -in $tmp/root_certificate.PEM -inform PEM -outform DER > $tmp/root_cert.DER 2>/dev/null
openssl genpkey -algorithm RSA -outform PEM -pkeyopt rsa_keygen_bits:2048 >$tmp/atte_key.PEM 2>/dev/null
openssl req -new -key $tmp/atte_key.PEM -subj "/CN=$CN/O=$OU/C=/CN=DRAGONBOARD TEST PKI – NOT SECURE/L=/O=/ST=/OU=01 0000000000000009 SW_ID/OU=02 0000000000000000 HW_ID" -days 7300 > $tmp/atte_csr.PEM 2>/dev/null
openssl x509 -req -in $tmp/atte_csr.PEM -CAkey $tmp/root_key.PEM -CA $tmp/root_certificate.PEM -days 7300 -set_serial 1 -extfile $tmp_att_file -sha256 -out $tmp/atte_cert.PEM 2>/dev/null
openssl x509 -in $tmp/atte_cert.PEM -inform PEM -outform DER > $tmp/atte_cert.DER 2>/dev/null
$EXECUTABLE $INFILE $OUTFILE $tmp/root_cert.DER $tmp/atte_cert.DER
rm -rf $tmp
echo done
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment