#===============================================================================
#
# App Core
#
# GENERAL DESCRIPTION
#    build script
#
#
#-------------------------------------------------------------------------------
#
#  $Header:  $
#  $DateTime: $
#  $Author: $
#  $Change: $
#                      EDIT HISTORY FOR FILE
#
#  This section contains schedulerents describing changes made to the module.
#  Notice that changes are listed in reverse chronological order.
#===============================================================================
Import('env')
env = env.Clone()
import os
import string

# Adding entry for current TA in external build sanity script which tests
# compilation of TAs in external build.
try:
  # Fetch the path of current Sconscript file.
  this_sconscript = (lambda x:x).__code__.co_filename
  env.ExtSdkBldSanity(this_sconscript)
except:
  pass

# Set this flag to true if tha current TA is chipset independent and doesn't 
# require to be rebuilt for every chipset.
env['CHIPSET_INDEPENDENT'] = True

#-------------------------------------------------------------------------------
# Build Target
#-------------------------------------------------------------------------------
target_name = "skm"

#env.Append(OUT_DIR = QSEE_APP_DIR + '/bsp/trustzone/qsapps/' + target_name + '/build')
env['APP_NAME'] = target_name

if env.get('CHIPSET_INDEPENDENT'):
    env['OUT_DIR'] = os.path.join(env['BUILD_ROOT'], 'apps/bsp/trustzone/qsapps/${APP_NAME}/build/') 


#-------------------------------------------------------------------------------
# DRK Feature Tags
#-------------------------------------------------------------------------------
LLVM_CHIPSETS = ['msm8937', 'msm8953', 'msm8996', 'msm8998', 'sdm670', 'sdm660', 'sdm845', 'sdm855', 'sm6150', 'sm7150', 'sdm439', 'sm8250', 'sm7250', 'saipan', 'sm8350', 'lahaina', 'sm7125', 'rennell', 'sm7225', 'bitra', 'sm7325', 'kodiak', 'waipio', 'divar']
STACK_HEAP_IN_APP_METADATA_CHIPSETS = ['sdm670', 'sdm845', 'sdm855', 'sm6150', 'sm7150', 'sm8250','sm7250', 'saipan', 'sm8350', 'lahaina', 'sm7125', 'rennell', 'sm7225', 'bitra', 'sm7325', 'kodiak', 'waipio', 'divar']
LOW_RESOURCES_CHIPSETS = ['apq8064']
USE_HWVAULT_CHIPSETS = ['lahaina', 'waipio']

DEVELOPER_LOCAL_BUILD = os.environ.get('DEVELOPER_LOCAL_BUILD')
BUILD_TOOL = "llvm" if env['CHIPSET'] in LLVM_CHIPSETS else "arm"
if env['CHIPSET'] == 'msm8952' or env['CHIPSET'] == 'msm8956':
  if os.environ.get('LLVMTOOLS') == 'LLVM':
    BUILD_TOOL = 'llvm'

SET_STACK_HEAP_IN_APP_METADATA = "True" if env['CHIPSET'] in STACK_HEAP_IN_APP_METADATA_CHIPSETS else "False"
USE_SECURE_APP_BUILDER = "True" if hasattr(env, 'SecureAppBuilder') \
                          and env['CHIPSET'] != "msm8937" \
                          else "False"
USE_LOG_ENCRYPTION = "False" if env['CHIPSET'] in LOW_RESOURCES_CHIPSETS else "True"
DRKVAR_USE_HWVAULT = "True" if env['CHIPSET'] in USE_HWVAULT_CHIPSETS else "False"

ENABLE_NEW_TA_BUILD = "False"
if os.environ.get('SUPPORT_NEW_TA_BUILD') == 'true' :
    ENABLE_NEW_TA_BUILD = "True"

if DEVELOPER_LOCAL_BUILD == "True":
    BUILD_MODE = os.getenv("MODE", "RELEASE").upper()
    assert BUILD_MODE in ["RELEASE", "DEBUG"]
    OS_TYPE = os.environ["OS_TYPE"].upper()
    PROC = "A53_64" if os.getenv("MACH_SWD", "") == "64" else "scorpion"
    USE_SCRYPTO = os.environ["USE_SCRYPTO"]
else:
    BUILD_MODE = "RELEASE"
    OS_TYPE = "ANDROID"
    USE_SCRYPTO = "False"

DRK_TARGET_BUILD_VARIANT =  "none"
if os.environ.get('TARGET_BUILD_VARIANT') == 'eng' :
    DRK_TARGET_BUILD_VARIANT = "eng"

SYSTEM_HIDL_ENABLED = "True"
QSEE_APP_DIR = env['BUILD_ROOT'] + '/apps'

COMMON_CPPDEFINES = [
   "USE_QSEE",
   BUILD_MODE,
   "USE_%s" % OS_TYPE,
   "BUILD_BOOT_CHAIN",
   "BUILD_BOOT_CHAIN_SPBL",
   "BOOT_LOADER",
   "BOOT_WATCHDOG_DISABLED",
   "FLASH_NAND_SINGLE_THREADED",
   "FLASH_CLIENT_BOOT",
   "FLASH_USE_DM_PAGES",
   "FEATURE_HS_USB_BASIC",
   "BOOT_SBL_H=\\\"boot_comdef.h\\\"",
   "BOOT_CUSTSBL_H=\\\"custsbl.h\\\"",
   "BOOT_MODULE_BUILD_VERSION=" + env['BUILD_VER'],
   "FEATURE_USES_TURBO",
   "RUMIBUILD",
]

if os.path.isfile(QSEE_APP_DIR + '/securemsm/secboot/auth/src/secboot_oem_secapp.xml'):
    import re
    from xml.etree import ElementTree as et
    f = open(QSEE_APP_DIR + '/securemsm/secboot/auth/src/secboot_oem_secapp.xml')
    rawData = f.read()
    f.close()
    xmlData = re.sub(r'type=([^"]\w*[^"])>', r'type="\1">', re.sub(r'#\w*\s"\w*.\w*"', '', rawData))
    if xmlData.find('<!--')==-1 and xmlData.find('-->')==-1:
        altDataSet = re.compile('[0-9A-Fa-f]{2}').findall(et.fromstring(xmlData).find('device').find('props').text)
        ALTNAME = "alt."
        for rawValue in altDataSet : ALTNAME += rawValue.upper()
        ALTNAME += "."
        if len(ALTNAME)>=6:
            if len(ALTNAME)>69:
                ALTNAME = ALTNAME[:68] + "."
            COMMON_CPPDEFINES += ["ALTNAME=\\\"%s\\\"" % ALTNAME]

env.Replace(SRC_DIR = QSEE_APP_DIR+'/securemsm/trustzone/qsapps/' + target_name + '/src')
env.Replace(LIB_DIR = QSEE_APP_DIR+'/securemsm/trustzone/qsapps/' + target_name + '/lib')
env.Replace(INC_DIR = QSEE_APP_DIR+'/securemsm/trustzone/qsapps/' + target_name + '/include')
env.Replace(TARGET_NAME = target_name)

#-------------------------------------------------------------------------------
# Compiler, object, and linker definitions
#-------------------------------------------------------------------------------

if BUILD_TOOL == "llvm":
  env.Append(CFLAGS = " -fPIC") # ' --apcs=/ropi/rwpi --lower_ropi --lower_rwpi')
  env.Append(CCFLAGS = " -fstack-protector")
  env.Append(CFLAGS = " -Werror")
  # Apply stack protection - requested by yj0729.kim at 17.12.05.
  env.Append(CFLAGS = ' -fstack-protector -fstack-protector-all')
#------------------------------------------------------------------------------
# We need to specify "neon" to generate SIMD instructions in 32-bit mode
#------------------------------------------------------------------------------
  if env['PROC'] == 'scorpion':
    env.Append(CCFLAGS = " -mfpu=neon ")
elif BUILD_TOOL =="arm":
  env.Append(CCFLAGS = " --gnu --c99 --no_vla")
  env.Append(CCFLAGS = " --protect_stack ")
  env.Append(CFLAGS = ' --apcs=/ropi/rwpi --lower_ropi --lower_rwpi')
  env.Append(ASFLAGS = ' --apcs=/ropi/rwpi ')
  # do not generate thumb code for inline assembler code
  env.Append(ARMCC_OPT = ' --arm')
  # Suppress Error: C9933W: Waiting for license...
  env.Append(ARMCC_OPT = ' --licretry --diag_suppress=9931,9933 --diag_remark=9933')
  # Apply stack protection - requested by yj0729.kim at 17.12.05.
  env.Append(CFLAGS = ' --protect_stack --protect-stack-all')

env.Append(CPPDEFINES = COMMON_CPPDEFINES)

APP_INCLUDES = [
    "${INC_DIR}/",
    "${INC_DIR}/common",
    "${INC_DIR}/common/platform/qsee",
    "${INC_DIR}/common/platform/android",
    "${INC_DIR}/crypto/",
    "${INC_DIR}/crypto/pbkdf/",
    "${INC_DIR}/crypto/x509/",
    "${INC_DIR}/skm/",
    "${INC_DIR}/skm/qsee/",
    "${INC_DIR}/logEncryptor",
    env['BUILD_ROOT'] + '/core/api/services',
    QSEE_APP_DIR+'/api/securemsm/trustzone/qsee',
]

#----------------------------------------------------------------------------
# App core Objects
#----------------------------------------------------------------------------

APP_CORE_ENTRY_SOURCES = [
    '${SRC_DIR}/skm/cryptoPlatform.c',
    '${SRC_DIR}/skm/keyManager.c',
    '${SRC_DIR}/skm/log.c',
    '${SRC_DIR}/skm/teeCmdExecuter.c',
    '${SRC_DIR}/skm/qsee/qseeAppMain.c',
    '${SRC_DIR}/skm/qsee/qseeCryptoApi.c',
    '${SRC_DIR}/skm/qsee/qseeSecureState.c',
    '${SRC_DIR}/crypto/cryptoEngine.c',
    '${SRC_DIR}/crypto/secMemoryManager.c',
    '${SRC_DIR}/crypto/sha_256_hash.c',
    '${SRC_DIR}/crypto/pbkdf/hmac_sha256.c',
    '${SRC_DIR}/crypto/pbkdf/pbkdf2.c',
    '${SRC_DIR}/crypto/x509/asn1build.c',
    '${SRC_DIR}/crypto/x509/asn1build_ec.c',
    '${SRC_DIR}/crypto/x509/asn1build_rsa.c',
    '${SRC_DIR}/crypto/x509/asn1.c',
    '${SRC_DIR}/crypto/x509/asn1ec.c',
    '${SRC_DIR}/crypto/x509/asn1gen.c',
    '${SRC_DIR}/crypto/x509/asn1rsa.c',
    '${SRC_DIR}/crypto/x509/certGenerator.c',
    '${SRC_DIR}/crypto/x509/certParser.c',
    '${SRC_DIR}/crypto/x509/x509v3.c',
    '${SRC_DIR}/common/TLV.c',
    '${SRC_DIR}/common/ServiceName.c',
    '${SRC_DIR}/logEncryptor/circularQueue.c',
    '${SRC_DIR}/logEncryptor/logEncryptor.c',
]
arm_libs = []

# crypto platform definitions
if USE_SCRYPTO == "True":
    env.Append( ARMCC_OPT = ' -DUSE_SCRYPTO')
    env.Append( ARMCC_OPT = ' -DOPENSSL_FIPS')
    APP_INCLUDES += [
      "${INCLUDEPATH}/../scrypto_qc/fips/include/openssl",
      "${INCLUDEPATH}/common/include/scrypto",
      "${INCLUDEPATH}/common/src/scrypto/openssl",
      "${INCLUDEPATH}/common/src/scrypto",
    ]
    APP_CORE_ENTRY_SOURCES += [
        "${SRC_DIR}/common/src/crypto/crypto_core/rsa.c",
        "${SRC_DIR}/common/src/crypto/crypto_core/ec.c",
        "${SRC_DIR}/scrypto_qc/fips/lib/fips_premain.c",
        "${SRC_DIR}/scrypto_qc/fips/lib/fips_static_hmac.c",
    ]
    # crypto platform static lib
    cc_static_lib = [
        "${LIB_DIR}/lib/qc_scrypto/env['CHIPSET'].lib",
    ]
else:
    # Openssl Mini.
    APP_INCLUDES += [ "${INC_DIR}/crypto/openssl", ]
    APP_CORE_ENTRY_SOURCES += [
        '${SRC_DIR}/crypto/openssl_mini/ex_data.c',
        '${SRC_DIR}/crypto/openssl_mini/mem_clr.c',
        '${SRC_DIR}/crypto/openssl_mini/memmgrs.c',
        '${SRC_DIR}/crypto/openssl_mini/aes/aes_core.c',
        '${SRC_DIR}/crypto/openssl_mini/aes/aes_gcm.c',
        '${SRC_DIR}/crypto/openssl_mini/aes/gcm128.c',
        '${SRC_DIR}/crypto/openssl_mini/asn1/a_int.c',
        '${SRC_DIR}/crypto/openssl_mini/asn1/a_bitstr.c',
        '${SRC_DIR}/crypto/openssl_mini/asn1/asn1_lib.c',
        '${SRC_DIR}/crypto/openssl_mini/asn1/a_type.c',
        '${SRC_DIR}/crypto/openssl_mini/asn1/tasn_dec.c',
        '${SRC_DIR}/crypto/openssl_mini/asn1/tasn_enc.c',
        '${SRC_DIR}/crypto/openssl_mini/asn1/tasn_fre.c',
        '${SRC_DIR}/crypto/openssl_mini/asn1/tasn_new.c',
        '${SRC_DIR}/crypto/openssl_mini/asn1/tasn_typ.c',
        '${SRC_DIR}/crypto/openssl_mini/asn1/tasn_utl.c',
        '${SRC_DIR}/crypto/openssl_mini/asn1/x_bignum.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_add.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_asm.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_ctx.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_div.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_gcd.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_exp.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_kron.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_lib.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_mod.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_mont.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_mul.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_prime.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_rand.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_recp.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_shift.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_sqr.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_sqrt.c',
        '${SRC_DIR}/crypto/openssl_mini/bn/bn_word.c',
        '${SRC_DIR}/crypto/openssl_mini/ec/ec.c',
        '${SRC_DIR}/crypto/openssl_mini/ec/ec_curve.c',
        '${SRC_DIR}/crypto/openssl_mini/ec/ec_cvt.c',
        '${SRC_DIR}/crypto/openssl_mini/ec/ec_key.c',
        '${SRC_DIR}/crypto/openssl_mini/ec/ec_lib.c',
        '${SRC_DIR}/crypto/openssl_mini/ec/ec_mult.c',
        '${SRC_DIR}/crypto/openssl_mini/ec/ec_oct.c',
        '${SRC_DIR}/crypto/openssl_mini/ec/ecp_mont.c',
        '${SRC_DIR}/crypto/openssl_mini/ec/ecp_oct.c',
        '${SRC_DIR}/crypto/openssl_mini/ec/ecp_smpl.c',
        '${SRC_DIR}/crypto/openssl_mini/ecdsa/ecs_asn1.c',
        '${SRC_DIR}/crypto/openssl_mini/ecdsa/ecs_lib.c',
        '${SRC_DIR}/crypto/openssl_mini/ecdsa/ecs_ossl.c',
        '${SRC_DIR}/crypto/openssl_mini/ecdsa/ecs_sign.c',
        '${SRC_DIR}/crypto/openssl_mini/ecdsa/ecs_vrf.c',
        '${SRC_DIR}/crypto/openssl_mini/lhash/lhash.c',
        '${SRC_DIR}/crypto/openssl_mini/rsa/rsa.c',
        '${SRC_DIR}/crypto/openssl_mini/rsa/rsa_lib.c',
        '${SRC_DIR}/crypto/openssl_mini/rsa/rsa_gen.c',
        '${SRC_DIR}/crypto/openssl_mini/stack/stack.c',
    ]

#-------------------------------------------------------------------------------
# Add definitions
#-------------------------------------------------------------------------------
if SYSTEM_HIDL_ENABLED == "True":
    env.Append( ARMCC_OPT = ' -DSYSTEM_ROOT_IMAGE_ENABLED')

# low resources definitions
if USE_LOG_ENCRYPTION == "False":
    env.Append( ARMCC_OPT = ' -DDISABLE_LOG_ENCRYPTION')

if DRK_TARGET_BUILD_VARIANT == "eng":
    env.Append( ARMCC_OPT = ' -DDRK_TEST_API_ENABLED')

#-------------------------------------------------------------------------------
# Add metadata to image
#-------------------------------------------------------------------------------

if ENABLE_NEW_TA_BUILD == "False" :
    md = {
           'appName':    target_name,
           'privileges': ['default',
                          'OEMUnwrapKeys',
                          'CertValidate',
                         ],
        }
else :
    md = {
           'appName':    target_name,
           'privileges': ['default',
                          'OEMUnwrapKeys',
                          'CertValidate',
                          'System',
                         ],
        }    

if SET_STACK_HEAP_IN_APP_METADATA == "True":
    md['heapSize'] = 0x40000
    md['stackSize'] = 0x40000


#------------------------------------------------------------------------------
# HwVault interface
#------------------------------------------------------------------------------
print("[DeviceRootKey] ENABLE_HWVAULT FOR DRK : " + str(DRKVAR_USE_HWVAULT))
if DRKVAR_USE_HWVAULT == "True":
    env.Append( ARMCC_OPT = ' -DDRKFEATURE_HWVAULT_ENABLE')
    DRKVAR_HWVAULT_LIB_PATH = QSEE_APP_DIR + "/securemsm/trustzone/qsapps/hwvault/public"
    APP_CORE_ENTRY_SOURCES += [
      DRKVAR_HWVAULT_LIB_PATH + "/src/HwVaultHal_api.c",
    ]
    APP_INCLUDES += [
      DRKVAR_HWVAULT_LIB_PATH + "/include",
    ]
    md['privileges'] += ['HwVaultHal']

print("[DeviceRootKey] ENABLE_NEW_TA_BUILD FOR SKM : " + str(ENABLE_NEW_TA_BUILD))
if ENABLE_NEW_TA_BUILD == "True":
    env.Append(LINKFLAGS=' -no-threads ') # Added to build TA in deterministic way in order to reduce the cost of duplicated signing

if USE_SECURE_APP_BUILDER == "True":
    if env["PROC"] == "scorpion":
        arm_libs.append(File(env.SubstRealPath('${MUSL32PATH}/lib/libc.a')))
    else:
        arm_libs.append(File(env.SubstRealPath('${MUSLPATH}/lib/libc.a')))

    if SET_STACK_HEAP_IN_APP_METADATA == "True":
        skm_units = env.SecureAppBuilder(
          sources = APP_CORE_ENTRY_SOURCES,
          includes = APP_INCLUDES,
          metadata = md,
          image = target_name,
          user_libs = arm_libs,
        )
    else:
        skm_units = env.SecureAppBuilder(
          sources = APP_CORE_ENTRY_SOURCES,
          includes = APP_INCLUDES,
          metadata = md,
          image = target_name,
          user_libs = arm_libs,
          stack_size = '0x40000',
          heap_size = '0x40000',
        )

    if hasattr(env, 'IMAGE_ALIASES'):
        for image in env['IMAGE_ALIASES']:
            op = env.Alias(image, skm_units)
    else:
        env.Alias(target_name, skm_units)

    Return('skm_units')