install_sgx_for_applicaiton_developer.sh 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. #!/bin/bash
  2. # Reference:
  3. # https://cc-enabling.trustedservices.intel.com/intel-sgx-sw-installation-guide-linux/02/installation_instructions/#intel-sgx-application-developer
  4. #TODO:
  5. # report error when curl fails to download files, e.g. due to network issues or incorrect URLs
  6. set -euo pipefail
  7. if [ "${DEBUG:-0}" -eq 1 ]; then
  8. set -o xtrace
  9. fi
  10. # Error trap handler - logs failure details and calls cleanup before exit
  11. error_handler() {
  12. local exit_code=$?
  13. local line_number=${1:-$LINENO}
  14. local bash_lineno=${2:-$BASH_LINENO}
  15. local last_command=${3:-$BASH_COMMAND}
  16. local function_stack=${4:-${FUNCNAME[*]}}
  17. # Log error context to file
  18. {
  19. echo "=== ERROR OCCURRED ==="
  20. echo "Exit Code: $exit_code"
  21. echo "Line Number: $line_number"
  22. echo "Bash Line: $bash_lineno"
  23. echo "Failed Command: $last_command"
  24. echo "Function Stack: $function_stack"
  25. echo "Timestamp: $(date '+%Y-%m-%d %H:%M:%S')"
  26. echo "======================"
  27. } >> "${LOG_FILE:-/tmp/install_sgx.log}" 2>/dev/null || true
  28. # Print concise error to stderr
  29. echo "ERROR: Script failed at line $line_number with exit code $exit_code" >&2
  30. echo "Failed command: $last_command" >&2
  31. echo "Check log file: ${LOG_FILE:-/tmp/install_sgx.log}" >&2
  32. # Call cleanup function if it exists
  33. if type cleanup >/dev/null 2>&1; then
  34. cleanup || true
  35. fi
  36. exit $exit_code
  37. }
  38. # Set up error trap
  39. trap 'error_handler $LINENO $BASH_LINENO "$BASH_COMMAND" "${FUNCNAME[*]}"' ERR
  40. # Platform will be detected dynamically by platform_detect() function
  41. # Supported platforms: Debian12, Debian11, Ubuntu22.04-server, Ubuntu20.04-server
  42. PLATFORM=""
  43. # Logging infrastructure
  44. LOG_FILE="/tmp/install_sgx.log"
  45. # Initialize log file with timestamp
  46. init_log() {
  47. echo "=== Intel SGX Installation Log - $(date) ===" > "${LOG_FILE}"
  48. echo "Platform: ${PLATFORM}" >> "${LOG_FILE}"
  49. echo "Script: $0" >> "${LOG_FILE}"
  50. echo "Started at: $(date '+%Y-%m-%d %H:%M:%S')" >> "${LOG_FILE}"
  51. echo "" >> "${LOG_FILE}"
  52. }
  53. # Log message with timestamp
  54. log_info() {
  55. echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "${LOG_FILE}"
  56. }
  57. # Execute command with output redirected to log
  58. log_exec() {
  59. log_info "Executing: $*"
  60. "$@" >>"$LOG_FILE" 2>&1
  61. }
  62. # Print environment sourcing instructions
  63. print_env_instructions() {
  64. log_info "Printing environment setup instructions"
  65. echo "========================================================================"
  66. echo " IMPORTANT: Before building or running SGX applications, you must run:"
  67. echo " source /opt/intel/sgxsdk/environment"
  68. echo " in your current shell to activate SGX SDK environment variables."
  69. echo "========================================================================"
  70. log_info "Environment setup instructions displayed to user"
  71. }
  72. check_sgx_packages() {
  73. log_info "Checking for existing SGX packages..."
  74. local packages=("libsgx-quote-ex" "libsgx-dcap-ql" "libsgx-enclave-common-dev" "libsgx-dcap-ql-dev" "libsgx-dcap-default-qpl-dev" "tee-appraisal-tool")
  75. local missing_packages=()
  76. for package in "${packages[@]}"; do
  77. if ! dpkg -l "$package" >> "${LOG_FILE}" 2>&1; then
  78. missing_packages+=("$package")
  79. log_info "Package $package not installed"
  80. else
  81. log_info "Package $package already installed"
  82. fi
  83. done
  84. if [ ${#missing_packages[@]} -eq 0 ]; then
  85. log_info "All SGX packages are already installed"
  86. return 0
  87. else
  88. log_info "Missing SGX packages: ${missing_packages[*]}"
  89. return 1
  90. fi
  91. }
  92. check_sgx_sdk() {
  93. log_info "Checking for existing SGX SDK..."
  94. if [ -d "/opt/intel/sgxsdk" ] && [ -f "/opt/intel/sgxsdk/environment" ]; then
  95. log_info "SGX SDK already installed at /opt/intel/sgxsdk"
  96. # Validate SDK installation by checking key components
  97. if [ -f "/opt/intel/sgxsdk/bin/sgx-gdb" ] && [ -d "/opt/intel/sgxsdk/include" ]; then
  98. log_info "SGX SDK installation appears complete"
  99. return 0
  100. else
  101. log_info "SGX SDK installation incomplete - missing key components"
  102. return 1
  103. fi
  104. else
  105. log_info "SGX SDK not found"
  106. return 1
  107. fi
  108. }
  109. check_sgx_repo() {
  110. log_info "Checking for existing SGX local repository..."
  111. if [ -d "/opt/intel/sgx_debian_local_repo" ] && [ -f "/etc/apt/sources.list.d/sgx_debian_local_repo.list" ]; then
  112. log_info "SGX local repository already configured"
  113. return 0
  114. else
  115. log_info "SGX local repository not configured"
  116. return 1
  117. fi
  118. }
  119. # Modular installation functions
  120. # Platform detection and configuration
  121. platform_detect() {
  122. log_info "Entering platform_detect() function"
  123. if [ ! -f "/etc/os-release" ]; then
  124. log_info "ERROR: /etc/os-release not found - cannot detect OS"
  125. echo "ERROR: Cannot detect operating system. /etc/os-release not found." >&2
  126. log_info "Exiting platform_detect() function"
  127. return 1
  128. fi
  129. # Parse OS information from /etc/os-release
  130. local os_id=$(grep '^ID=' /etc/os-release | cut -d'=' -f2 | tr -d '"')
  131. local version_id=$(grep '^VERSION_ID=' /etc/os-release | cut -d'=' -f2 | tr -d '"')
  132. log_info "Raw OS detection: ID=${os_id}, VERSION_ID=${version_id}"
  133. # Determine platform string based on OS and version
  134. case "${os_id}" in
  135. "ubuntu")
  136. case "${version_id}" in
  137. "20.04")
  138. PLATFORM="Ubuntu20.04-server"
  139. ;;
  140. "22.04")
  141. PLATFORM="Ubuntu22.04-server"
  142. ;;
  143. *)
  144. log_info "ERROR: Unsupported Ubuntu version ${version_id}. Supported: 20.04, 22.04"
  145. echo "ERROR: Unsupported Ubuntu version ${version_id}. This script supports Ubuntu 20.04 and 22.04 only." >&2
  146. log_info "Exiting platform_detect() function"
  147. return 1
  148. ;;
  149. esac
  150. ;;
  151. "debian")
  152. case "${version_id}" in
  153. "11")
  154. PLATFORM="Debian11"
  155. ;;
  156. "12")
  157. PLATFORM="Debian12"
  158. ;;
  159. *)
  160. log_info "ERROR: Unsupported Debian version ${version_id}. Supported: 11, 12"
  161. echo "ERROR: Unsupported Debian version ${version_id}. This script supports Debian 11 and 12 only." >&2
  162. log_info "Exiting platform_detect() function"
  163. return 1
  164. ;;
  165. esac
  166. ;;
  167. *)
  168. log_info "ERROR: Unsupported OS ${os_id}. Supported: ubuntu, debian"
  169. echo "ERROR: Unsupported operating system '${os_id}'. This script supports Ubuntu and Debian only." >&2
  170. log_info "Exiting platform_detect() function"
  171. return 1
  172. ;;
  173. esac
  174. log_info "Successfully detected platform: ${PLATFORM}"
  175. echo "Detected platform: ${PLATFORM}"
  176. log_info "Exiting platform_detect() function"
  177. return 0
  178. }
  179. # Install SGX packages and SDK
  180. install_packages() {
  181. log_info "Entering install_packages() function"
  182. # Skip repo setup if already configured
  183. if ! check_sgx_repo; then
  184. log_info "Setting up SGX local repository..."
  185. pushd /tmp >> "${LOG_FILE}" 2>&1
  186. log_exec curl -fsSLO \
  187. https://download.01.org/intel-sgx/latest/linux-latest/distro/${PLATFORM}/sgx_debian_local_repo.tgz
  188. local_sum=$(sha256sum sgx_debian_local_repo.tgz | awk '{print $1}')
  189. remote_sum=$(curl -s https://download.01.org/intel-sgx/latest/dcap-latest/linux/SHA256SUM_dcap_1.24.cfg | grep "distro/${PLATFORM}/sgx_debian_local_repo.tgz" | awk '{print $1}')
  190. if [[ "$local_sum" == "$remote_sum" ]]; then
  191. log_info "Checksum matches"
  192. else
  193. log_info "Checksum mismatch!"
  194. fi
  195. log_exec sudo mkdir -p /opt/intel
  196. log_exec sudo tar xzf sgx_debian_local_repo.tgz -C /opt/intel
  197. echo 'deb [signed-by=/etc/apt/keyrings/intel-sgx-keyring.asc arch=amd64] file:///opt/intel/sgx_debian_local_repo bookworm main' \
  198. | sudo tee /etc/apt/sources.list.d/sgx_debian_local_repo.list | tee -a "${LOG_FILE}" > /dev/null
  199. log_exec sudo cp /opt/intel/sgx_debian_local_repo/keys/intel-sgx.key /etc/apt/keyrings/intel-sgx-keyring.asc
  200. popd >> "${LOG_FILE}" 2>&1
  201. else
  202. log_info "SGX repository already configured, skipping setup"
  203. fi
  204. # Install SGX packages only if missing
  205. if ! check_sgx_packages; then
  206. log_info "Installing missing SGX packages..."
  207. log_exec sudo apt-get update
  208. log_exec sudo apt-get install -y libsgx-quote-ex libsgx-dcap-ql
  209. else
  210. log_info "SGX packages already installed, skipping"
  211. fi
  212. # Install build dependencies
  213. log_exec sudo apt-get update --quiet
  214. log_exec sudo apt-get install --quiet -y build-essential python3
  215. log_exec sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1
  216. # Install Intel SGX SDK only if missing
  217. if ! check_sgx_sdk; then
  218. log_info "Installing Intel SGX SDK for Application Developer..."
  219. pushd /opt/intel >> "${LOG_FILE}" 2>&1
  220. log_exec sudo curl -fsSLo sgx_linux_x64_sdk.bin \
  221. https://download.01.org/intel-sgx/latest/linux-latest/distro/${PLATFORM}/sgx_linux_x64_sdk_2.27.100.1.bin
  222. log_exec sudo chmod +x sgx_linux_x64_sdk.bin
  223. log_exec sudo ./sgx_linux_x64_sdk.bin --prefix /opt/intel
  224. # Log environment setup instructions for user
  225. log_info "SGX SDK installation completed successfully."
  226. log_info "IMPORTANT: To use the SGX SDK in your development session:"
  227. log_info " 1. Run: source /opt/intel/sgxsdk/environment"
  228. log_info " 2. This must be done in each shell session where you use SGX"
  229. log_info " 3. Environment variables are session-specific and cannot be exported by this script"
  230. log_info " 4. Consider adding 'source /opt/intel/sgxsdk/environment' to your ~/.bashrc for automatic setup"
  231. popd >> "${LOG_FILE}" 2>&1
  232. else
  233. log_info "SGX SDK already installed, skipping"
  234. fi
  235. # Install Developer packages for Intel SGX only if missing
  236. if ! check_sgx_packages; then
  237. log_info "Installing Intel SGX Developer packages..."
  238. log_exec sudo apt-get install -y libsgx-enclave-common-dev \
  239. libsgx-dcap-ql-dev \
  240. libsgx-dcap-default-qpl-dev \
  241. tee-appraisal-tool
  242. else
  243. log_info "SGX Developer packages already installed, skipping"
  244. fi
  245. log_info "Exiting install_packages() function"
  246. return 0
  247. }
  248. # Validate the installation was successful
  249. validate_installation() {
  250. log_info "Entering validate_installation() function"
  251. local validation_failed=0
  252. # Re-check all components after installation
  253. if ! check_sgx_packages; then
  254. log_info "VALIDATION FAILED: SGX packages not properly installed"
  255. validation_failed=1
  256. fi
  257. if ! check_sgx_sdk; then
  258. log_info "VALIDATION FAILED: SGX SDK not properly installed"
  259. validation_failed=1
  260. fi
  261. if ! check_sgx_repo; then
  262. log_info "VALIDATION FAILED: SGX repository not properly configured"
  263. validation_failed=1
  264. fi
  265. if [ $validation_failed -eq 0 ]; then
  266. log_info "VALIDATION SUCCESS: All SGX components properly installed"
  267. else
  268. log_info "VALIDATION FAILED: Some SGX components failed installation"
  269. log_info "Exiting validate_installation() function"
  270. return 1
  271. fi
  272. log_info "Exiting validate_installation() function"
  273. return 0
  274. }
  275. # Clean up temporary files
  276. cleanup() {
  277. log_info "Entering cleanup() function"
  278. # Clean up any temporary files in /tmp related to SGX installation
  279. if [ -f "/tmp/sgx_debian_local_repo.tgz" ]; then
  280. log_info "Removing temporary SGX repository archive"
  281. rm -f /tmp/sgx_debian_local_repo.tgz
  282. fi
  283. # Additional cleanup can be added here as needed
  284. log_info "Temporary file cleanup completed"
  285. log_info "Exiting cleanup() function"
  286. return 0
  287. }
  288. # Initialize logging
  289. init_log
  290. log_info "Starting idempotency checks..."
  291. # Check if everything is already installed
  292. if check_sgx_packages && check_sgx_sdk && check_sgx_repo; then
  293. log_info "Complete SGX installation detected - no action needed"
  294. echo "Intel SGX for Application Developer is already installed and configured."
  295. print_env_instructions
  296. exit 0
  297. fi
  298. log_info "Partial or missing SGX installation detected - proceeding with installation"
  299. # Main installation flow using modular functions
  300. log_info "Starting Intel SGX for Application Developer installation..."
  301. # Execute installation steps in modular fashion
  302. platform_detect
  303. if [ $? -ne 0 ]; then
  304. log_info "Platform detection failed"
  305. exit 1
  306. fi
  307. install_packages
  308. if [ $? -ne 0 ]; then
  309. log_info "Package installation failed"
  310. exit 1
  311. fi
  312. validate_installation
  313. if [ $? -ne 0 ]; then
  314. log_info "Installation validation failed"
  315. exit 1
  316. fi
  317. cleanup
  318. if [ $? -ne 0 ]; then
  319. log_info "Cleanup failed"
  320. exit 1
  321. fi
  322. cleanup
  323. if [ $? -ne 0 ]; then
  324. log_info "Cleanup failed"
  325. exit 1
  326. fi
  327. echo "Intel SGX for Application Developer installation completed."
  328. print_env_instructions