misc: Import SM-G900H kernel source code

* Samsung Package Version: G800HXXU1CRJ1
    * CAF Tag: LA.BF.1.1.3-00110-8x26.0
This commit is contained in:
Francescodario Cuzzocrea
2019-08-02 15:14:10 +02:00
parent 9c7c217b9e
commit 85baa390bf
5281 changed files with 2758302 additions and 38068 deletions
+3
View File
@@ -153,6 +153,9 @@ def build(target):
devnull = open('/dev/null', 'r')
subprocess.check_call(['make', 'O=%s' % dest_dir,
'SELINUX_DEFCONFIG=selinux_defconfig',
'SELINUX_LOG_DEFCONFIG=selinux_log_defconfig',
'TIMA_DEFCONFIG=tima_defconfig',
'%s_defconfig' % target], env=make_env, stdin=devnull)
devnull.close()
+235
View File
@@ -0,0 +1,235 @@
#!/bin/bash
# fips_crypto_hmac.sh
#
# Author : Rohit Kothari (r.kothari@samsung.com)
# Created on : 14 Feb 2014
# Copyright (c) Samsung Electronics 2014
# Given a vmlinux file and a System.map, this scripts finds bytes belonging to
# Kernel Crypto within vmlinux file.(Under section .text, .init.text, .exit.text and .rodata)
# After collecting all the bytes, it calculates a hmac(sha256) on those bytes.
# Generated hmac is put back into a crypto rodata variable within vmlinux file itself.
# This makes the build time hmac available at runtime, for integrity check.
#
# To find crypto bytes, this scripts heavily relies on output of arm-eabi-readelf.
# If the output of arm-eabi-readelf changes in future, this script might need changes.
#
# Pre-conditions : $READELF, $HOSTCC variables are set.
#
#
if test $# -ne 2; then
echo "Usage: $0 vmlinux System.map"
exit 1
fi
vmlinux_var=$1
system_map_var=$2
if [[ -z "$vmlinux_var" || -z "$system_map_var" || -z "$READELF" || -z "$HOSTCC" ]]; then
echo "$0 : variables not set"
exit 1
fi
if [[ ! -f $vmlinux_var || ! -f $system_map_var ]]; then
echo "$0 : files does not exist"
exit 1
fi
rm -f vmlinux.elf
$READELF -S $vmlinux_var > vmlinux.elf
retval=$?
if [ $retval -ne 0 ]; then
echo "$0 : $READELF returned error"
exit 1
fi
declare -A array
# FOR GENERIC CRYPTO FILES #awk fields to cut
array[0]=".text first_crypto_text last_crypto_text \$5 \$6"
array[1]=".rodata first_crypto_rodata last_crypto_rodata \$5 \$6"
array[2]=".init.text first_crypto_init last_crypto_init \$4 \$5"
array[3]=".exit.text first_crypto_exit last_crypto_exit \$4 \$5"
# # FOR ASM CRYPTO FILES
array[4]=".text first_crypto_asm_text last_crypto_asm_text \$5 \$6"
array[5]=".rodata first_crypto_asm_rodata last_crypto_asm_rodata \$5 \$6"
array[6]=".init.text first_crypto_asm_init last_crypto_asm_init \$4 \$5"
array[7]=".exit.text first_crypto_asm_exit last_crypto_asm_exit \$4 \$5"
rm -f offsets_sizes.txt
#Addresses retrieved must be a valid hex
reg='^[0-9A-Fa-f]+$'
#Total bytes of all crypto sections scanned. Used later for error checking
total_bytes=0;
# For each type of Section :
# first_addr = Address of first_crypto_text, first_crypto_rodata, etc.
# last_addr = Address of last_crypto_text, last_crypto_rodata etc.
# start_addr = Starting Address of a section within vmlinux
# offset = Offset in vmlinux file where the section begins
# file_offset = Offset in vmlinux file where the crypto bytes begins.
# size = size of crypto bytes.
# Output is offsets_sizes.txt, of the format
# Section Name crypto_bytes_offset crypto_bytes_size
# (in decimal) (in decimal)
# .text 2531072 114576
# .rodata 9289648 55388
# : : :
for i in "${array[@]}"; do
var1=var2=var3=var4=var5=""
first_addr=last_addr=start_addr=offset=file_offset=size=""
k=1
#This loop creates var1, var2 etc and set them to individual strings of a row in array
for j in $i; do
export var$k=$j
let k+=1
done
first_addr=`cat $system_map_var|grep -w $var2|awk '{print $1}'`
if [[ ! $first_addr =~ $reg ]]; then echo "$0 : first_addr invalid"; exit 1; fi
last_addr=`cat $system_map_var|grep -w $var3|awk '{print $1}'`
if [[ ! $last_addr =~ $reg ]]; then echo "$0 : last_addr invalid"; exit 1; fi
start_addr=`cat vmlinux.elf |grep -w $var1|grep PROGBITS|awk '{print '$var4'}'`
if [[ ! $start_addr =~ $reg ]]; then echo "$0 : start_addr invalid"; exit 1; fi
offset=`cat vmlinux.elf |grep -w $var1|grep PROGBITS|awk '{print '$var5'}'`
if [[ ! $offset =~ $reg ]]; then echo "$0 : offset invalid"; exit 1; fi
if [[ $((16#$first_addr)) -lt $((16#$start_addr)) ]]; then echo "$0 : first_addr < start_addr"; exit 1; fi
if [[ $((16#$last_addr)) -le $((16#$first_addr)) ]]; then echo "$0 : last_addr <= first_addr"; exit 1; fi
file_offset=`expr $((16#$offset)) + $((16#$first_addr)) - $((16#$start_addr))`
if [[ $file_offset -le 0 ]]; then echo "$0 : file_offset invalid"; exit 1; fi
size=`expr $((16#$last_addr)) - $((16#$first_addr))`
if [[ $size -le 0 ]]; then echo "$0 : crypto section size invalid"; exit 1; fi
echo "$var1 " $file_offset " " $size >> offsets_sizes.txt
let "total_bytes += `expr $((16#$last_addr)) - $((16#$first_addr))`"
done
if [[ ! -f offsets_sizes.txt ]]; then
echo "$0 : offset_sizes.txt does not exist"
exit 1
fi
rm -f fips_crypto_utils
$HOSTCC -o fips_crypto_utils $srctree/scripts/fips_crypto_utils.c
retval=$?
if [ $retval -ne 0 ]; then
echo "$0 : $HOSTCC returned error"
exit 1
fi
rm -f builtime_bytes.txt #used for debugging
rm -f builtime_bytes.bin #used for calculating hmac
date_var=`date`
echo "Created on : " $date_var > builtime_bytes.txt
#Using offsets_sizes.txt, dump crypto bytes from vmlinux file into builtime_bytes.bin
#Also gather printf's into builtime_bytes.txt, for debugging if required
while read args; do
./fips_crypto_utils -g $vmlinux_var $args builtime_bytes.bin >> builtime_bytes.txt
retval=$?
if [ $retval -ne 0 ]; then
echo "$0 : fips_crypto_utils : unable to gather crypto bytes from vmlinux"
exit 1
fi
echo "" >> builtime_bytes.txt
done < offsets_sizes.txt # <================== offsets_sizes.txt
if [[ ! -f builtime_bytes.bin ]]; then
echo "$0 : builtime_bytes.bin does not exist"
exit 1
fi
file_size=`cat builtime_bytes.bin| wc -c`
# Make sure that file size of crypto_hmac.bin is as expected
if [ $total_bytes -ne $file_size ]; then
echo "$0: Bytes mismatch"
exit 1
fi
key="The quick brown fox jumps over the lazy dog"
# Now, generate the hmac.
openssl dgst -sha256 -hmac "$key" -binary -out crypto_hmac.bin builtime_bytes.bin
retval=$?
if [ $retval -ne 0 ]; then
echo "$0 : openssl dgst command returned error"
exit 1
fi
# Just, for debugging, print the same hmac on console
openssl dgst -sha256 -hmac "$key" builtime_bytes.bin
retval=$?
if [ $retval -ne 0 ]; then
echo "$0 : openssl dgst command returned error"
exit 1
fi
if [[ ! -f crypto_hmac.bin ]]; then
echo "$0 : crypto_hmac.bin does not exist"
exit 1
fi
file_size=`cat crypto_hmac.bin| wc -c`
# hmac(sha256) produces 32 bytes of hmac
if [ $file_size -ne 32 ]; then
echo "$0: Unexpected size of Hash file : " $file_size
exit 1
fi
# Now that we have the hmac, update this hmac into an rodata "builtime_crypto_hmac" varialble
# in vmlinux file.
# This variable has a place holder 32 bytes that will be over-written with generated hmac.
# This way, this build time hmac, will be available as a read-only variable at run-time.
first_addr=`cat $system_map_var|grep -w "builtime_crypto_hmac"|awk '{print $1}' `
if [[ ! $first_addr =~ $reg ]]; then echo "$0 : first_addr of hmac variable invalid"; exit 1; fi
start_addr=`cat vmlinux.elf |grep -w ".rodata"|grep PROGBITS|awk '{print $5}' `
if [[ ! $start_addr =~ $reg ]]; then echo "$0 : start_addr of .rodata invalid"; exit 1; fi
offset=`cat vmlinux.elf |grep -w ".rodata"|grep PROGBITS| awk '{print $6}' `
if [[ ! $offset =~ $reg ]]; then echo "$0 : offset of .rodata invalid"; exit 1; fi
if [[ $((16#$first_addr)) -le $((16#$start_addr)) ]]; then echo "$0 : hmac var first_addr <= start_addr"; exit 1; fi
hmac_offset=`expr $((16#$offset)) + $((16#$first_addr)) - $((16#$start_addr))`
if [[ $hmac_offset -le 0 ]]; then echo "$0 : hmac_offset invalid"; exit 1; fi
# This does the actual update of hmac into vmlinux file, at given offset
./fips_crypto_utils -u $vmlinux_var crypto_hmac.bin $hmac_offset
retval=$?
if [ $retval -ne 0 ]; then
echo "$0 : fips_crypto_utils : unable to update hmac in vmlinux"
exit 1
fi
rm -f crypto_hmac.bin
rm -f builtime_bytes.txt
rm -f builtime_bytes.bin
rm -f fips_crypto_utils
rm -f vmlinux.elf
rm -f offsets_sizes.txt
# And we are done...
+256
View File
@@ -0,0 +1,256 @@
/*
* Utility functions called from fips_crypto_hmac.sh.
*
* executed during Kernel build
*
*
* Author : Rohit Kothari (r.kothari@samsung.com)
* Date : 11 Feb 2014
*
* Copyright (c) 2014 Samsung Electronics
*
*/
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char **argv)
{
if (argc < 2)
{
printf ("\nUsage : \n");
printf ("fips_crypto_utils -u vmlinux_file hmac_file offset");
printf ("fips_crypto_utils -g vmlinux_file section_name offset size out_file");
printf ("\n");
return -1;
}
if (!strcmp ("-u", argv[1]))
{
unsigned long offset = 0;
unsigned char * vmlinux_file = NULL;
unsigned char * hmac_file = NULL;
if (argc != 5)
{
printf ("\nUsage : \n");
printf ("fips_crypto_utils -u vmlinux_file hmac_file offset");
printf ("\n");
return -1;
}
vmlinux_file = argv[2];
hmac_file = argv[3];
offset = atol(argv[4]);
if (!vmlinux_file || !hmac_file || !offset)
{
printf ("./fips_crypto_utils -u vmlinux_file hmac_file offset");
return -1;
}
return update_crypto_hmac (vmlinux_file, hmac_file, offset);
}
else if (!strcmp ("-g", argv[1]))
{
const char * in_file = NULL;
const char * section_name = NULL;
unsigned long offset = 0;
unsigned long size = 0;
const char * out_file = NULL;
if (argc != 7)
{
printf ("\nUsage : \n");
printf ("./fips_crypto_utils -g vmlinux_file section_name offset size out_file");
printf ("\n");
return -1;
}
in_file = argv[2];
section_name = argv[3];
offset = atol(argv[4]);
size = atol(argv[5]);
out_file = argv[6];
if (!in_file || !section_name || !offset || !size || !out_file)
{
printf ("./fips_crypto_utils -g vmlinux_file section_name offset size out_file");
return -1;
}
return collect_crypto_bytes (in_file, section_name, offset, size, out_file);
}
else
{
printf ("\nUsage : \n");
printf ("fips_crypto_utils -u vmlinux_file hmac_file offset");
printf ("fips_crypto_utils -g vmlinux_file section_name offset size out_file");
printf ("\n");
}
return -1;
}
/*
* Given a vmlinux file, dumps "size" bytes from given "offset" to output file
* in_file : absolute path to vmlinux file
* section_name : Used only for printing / debugging
* offset : offset in file from where to dump bytes
* size : how many bytes to dump
* out_file : Output file, where to dump bytes.
* Open in append mode, to keep previous bytes, if present
* Caller need to clean up before 1st call
*
* Returns 0, if success
* -1, if error
*/
int
collect_crypto_bytes (const char * in_file, const char * section_name, unsigned long offset,
unsigned long size, const char * out_file)
{
FILE * in_fp = NULL;
FILE * out_fp = NULL;
unsigned int i = 0;
unsigned char data = 0;
if (!in_file || !section_name || !offset || !size || !out_file)
{
printf ("collect_crypto_bytes : Invalid arguments");
return -1;
}
printf ("Section : %s\n", section_name);
in_fp = fopen (in_file, "r");
if (!in_fp)
{
printf ("Unable to open file : %s", in_file);
return -1;
}
if (fseek (in_fp, offset, SEEK_SET) != 0 )
{
printf ("Unable to seek file : %s", in_file);
fclose (in_fp);
return -1;
}
out_fp = fopen (out_file, "ab");
if (!out_fp)
{
printf ("Unable to open file : %s", out_file);
fclose(in_fp);
return -1;
}
for (i = 1; i <= size; i++)
{
if ( 1 != fread (&data, sizeof(unsigned char), 1, in_fp))
{
printf ("Unable to read 1 byte from file : %s", in_file);
fclose (in_fp);
fclose (out_fp);
return -1;
}
printf ("%02x ", data);
if (1 != fwrite (&data, 1, 1, out_fp))
{
printf ("Unable to write 1 byte to file : %s", out_file);
fclose (in_fp);
fclose (out_fp);
return -1;
}
if ( !(i % 16))
printf ("\n");
}
fclose (in_fp);
fclose (out_fp);
return 0;
}
#define SHA256_DIGEST_SIZE 32
/*
* Given a vmlinux file, overwrites bytes at given offset with hmac bytes, available in
* hmac file.
* Return 0, if Success
* -1, if Error
*/
int
update_crypto_hmac (const char * vmlinux_path, const char * hmac_path, unsigned long offset)
{
FILE * vmlinux_fp = NULL;
FILE * hmac_fp = NULL;
int i = 0, j = 0;
unsigned char hmac[SHA256_DIGEST_SIZE];
if (!vmlinux_path || !hmac_path || !offset)
{
printf ("FIPS update_crypto_hmac : Invalid Params");
return -1;
}
vmlinux_fp = fopen (vmlinux_path, "r+b");
if (!vmlinux_fp)
{
printf ("Unable to open vmlinux file ");
return -1;
}
hmac_fp = fopen (hmac_path, "rb");
if (!hmac_fp)
{
printf ("Unable to open hmac file ");
fclose (vmlinux_fp);
return -1;
}
if (SHA256_DIGEST_SIZE != fread (&hmac, sizeof(unsigned char), SHA256_DIGEST_SIZE, hmac_fp))
{
printf ("Unable to read %d bytes from hmac file", SHA256_DIGEST_SIZE);
fclose (hmac_fp);
fclose (vmlinux_fp);
return -1;
}
#if 0
printf ("Hash : ");
for (i = 0; i < sizeof(hmac); i++)
printf ("%02x ", hmac[i]);
printf ("\n");
printf ("Offset : %ld", offset);
#endif
if (fseek (vmlinux_fp, offset, SEEK_SET) != 0 )
{
printf ("Unable to seek into vmlinux file.");
fclose (hmac_fp);
fclose (vmlinux_fp);
return -1;
}
if (SHA256_DIGEST_SIZE != fwrite (hmac, sizeof(unsigned char), SHA256_DIGEST_SIZE, vmlinux_fp))
{
printf ("Unable to write %d byte into vmlinux", SHA256_DIGEST_SIZE);
fclose (hmac_fp);
fclose (vmlinux_fp);
return -1;
}
fclose (vmlinux_fp);
fclose (hmac_fp);
return 0;
}
+21
View File
@@ -78,6 +78,27 @@ allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf
PHONY += listnewconfig oldnoconfig savedefconfig defconfig
ifneq ($(VARIANT_DEFCONFIG),)
export KCONFIG_VARIANT := arch/$(SRCARCH)/configs/$(VARIANT_DEFCONFIG)
endif
ifneq ($(DEBUG_DEFCONFIG),)
export KCONFIG_DEBUG := arch/$(SRCARCH)/configs/$(DEBUG_DEFCONFIG)
endif
ifneq ($(SELINUX_DEFCONFIG),)
export KCONFIG_SELINUX := arch/$(SRCARCH)/configs/$(SELINUX_DEFCONFIG)
endif
ifneq ($(SELINUX_LOG_DEFCONFIG),)
export KCONFIG_LOG_SELINUX := arch/$(SRCARCH)/configs/$(SELINUX_LOG_DEFCONFIG)
endif
ifneq ($(TIMA_DEFCONFIG),)
export KCONFIG_TIMA := arch/$(SRCARCH)/configs/$(TIMA_DEFCONFIG)
endif
listnewconfig oldnoconfig: $(obj)/conf
$< --$@ $(Kconfig)
+58 -3
View File
@@ -559,6 +559,61 @@ int main(int ac, char **av)
"***\n"), defconfig_file);
exit(1);
}
name = getenv("KCONFIG_SELINUX");
printf("KCONFIG_SELINUX(%s)\n", name);
if (name) {
if (conf_read_simple(name, S_DEF_USER, false)) {
printf(_("***\n"
"*** Can't find selinux configuration \"%s\"!\n"
"***\n"), name);
exit(1);
}
}
name = getenv("KCONFIG_LOG_SELINUX");
printf("KCONFIG_LOG_SELINUX(%s)\n", name);
if (name) {
if (conf_read_simple(name, S_DEF_USER, false)) {
printf(_("***\n"
"*** Can't find selinux log configuration \"%s\"!\n"
"***\n"), name);
exit(1);
}
}
name = getenv("KCONFIG_TIMA");
printf("KCONFIG_TIMA(%s)\n", name);
if (name) {
if (conf_read_simple(name, S_DEF_USER, false)) {
printf(_("***\n"
"*** Can't find tima log configuration \"%s\"!\n"
"***\n"), name);
exit(1);
}
}
name = getenv("KCONFIG_VARIANT");
printf("KCONFIG_VARIANT(%s)\n", name);
if (name) {
if (conf_read_simple(name, S_DEF_USER, false)) {
printf(_("***\n"
"*** Can't find variant configuration \"%s\"!\n"
"***\n"), name);
exit(1);
}
} else {
printf(_("***\n"
"*** You must specify VARIANT_DEFCONFIG !\n"
"***\n"));
exit(1);
}
name = getenv("KCONFIG_DEBUG");
printf("KCONFIG_DEBUG(%s)\n", name);
if (name) {
if (conf_read_simple(name, S_DEF_USER, false)) {
printf(_("***\n"
"*** Can't find debug configuration \"%s\"!\n"
"***\n"), name);
exit(1);
}
}
break;
case savedefconfig:
case silentoldconfig:
@@ -575,7 +630,7 @@ int main(int ac, char **av)
case randconfig:
name = getenv("KCONFIG_ALLCONFIG");
if (name && !stat(name, &tmpstat)) {
conf_read_simple(name, S_DEF_USER);
conf_read_simple(name, S_DEF_USER, true);
break;
}
switch (input_mode) {
@@ -587,9 +642,9 @@ int main(int ac, char **av)
default: break;
}
if (!stat(name, &tmpstat))
conf_read_simple(name, S_DEF_USER);
conf_read_simple(name, S_DEF_USER, true);
else if (!stat("all.config", &tmpstat))
conf_read_simple("all.config", S_DEF_USER);
conf_read_simple("all.config", S_DEF_USER, true);
break;
default:
break;
+6 -4
View File
@@ -182,7 +182,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
return 0;
}
int conf_read_simple(const char *name, int def)
int conf_read_simple(const char *name, int def, int sym_init)
{
FILE *in = NULL;
char line[1024];
@@ -229,6 +229,8 @@ load:
conf_unsaved = 0;
def_flags = SYMBOL_DEF << def;
if (!sym_init)
goto readsym;
for_all_symbols(i, sym) {
sym->flags |= SYMBOL_CHANGED;
sym->flags &= ~(def_flags|SYMBOL_VALID);
@@ -246,7 +248,7 @@ load:
sym->def[def].tri = no;
}
}
readsym:
while (fgets(line, sizeof(line), in)) {
conf_lineno++;
sym = NULL;
@@ -349,7 +351,7 @@ int conf_read(const char *name)
sym_set_change_count(0);
if (conf_read_simple(name, S_DEF_USER))
if (conf_read_simple(name, S_DEF_USER, true))
return 1;
for_all_symbols(i, sym) {
@@ -780,7 +782,7 @@ static int conf_split_config(void)
int res, i, fd;
name = conf_get_autoconfig_name();
conf_read_simple(name, S_DEF_AUTO);
conf_read_simple(name, S_DEF_AUTO, true);
if (chdir("include/config"))
return 1;
+1 -1
View File
@@ -3,7 +3,7 @@
/* confdata.c */
P(conf_parse,void,(const char *name));
P(conf_read,int,(const char *name));
P(conf_read_simple,int,(const char *name, int));
P(conf_read_simple,int,(const char *name, int, int));
P(conf_write_defconfig,int,(const char *name));
P(conf_write,int,(const char *name));
P(conf_write_autoconf,int,(void));
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
BINARY_NAME=$1
MAKE_FIPS_BINARY()
{
openssl dgst -sha256 -hmac 12345678 -binary -out \
$BINARY_NAME.hmac $BINARY_NAME
cat $BINARY_NAME $BINARY_NAME.hmac > $BINARY_NAME.digest
cp -f $BINARY_NAME.digest $BINARY_NAME
rm -f $BINARY_NAME.digest $BINARY_NAME.hmac
}
echo "Make kernel fips binary.."
MAKE_FIPS_BINARY
echo "Done."