1
1
---
2
2
title : Arm®v8-M Security Extensions <br /> Requirements on Development Tools
3
- version : 1.3
4
- date-of-issue : 04 August 2023
3
+ version : 1.4
4
+ date-of-issue : 05 April 2024
5
5
set-quote-highlight : true
6
6
# LaTeX specific variables
7
- copyright-text :
Copyright 2019, 2021-2023 Arm Limited and/or its affiliates <[email protected] >.
8
- draftversion : false
7
+ copyright-text :
Copyright 2019, 2021-2024 Arm Limited and/or its affiliates <[email protected] >.
8
+ draftversion : true
9
9
# Jekyll specific variables
10
10
header_counter : true
11
11
toc : true
@@ -155,6 +155,13 @@ Copyright 2019, 2021-2023 Arm Limited and/or its affiliates <open-source-office@
155
155
[ Non-secure function pointers] ( #non-secure-function-pointer ) .
156
156
* Fixed typos.
157
157
158
+ #### Changes for next release
159
+
160
+ * Added [ Requirement #47 ] ( #requirement-47 ) to address a security issue in the
161
+ handling of arguments to CMSE Entry functions.
162
+ * Added [ Requirement #58 ] ( #requirement-58 ) to address a security issue in the
163
+ handling of return values from CMSE Non-secure calls.
164
+
158
165
## References
159
166
160
167
This document refers to the following documents.
@@ -1138,9 +1145,51 @@ caller stack frame](#figure5).
1138
1145
1139
1146

1140
1147
1141
- ### Return from an entry function
1148
+ Calls from Non-secure state follow the [[AAPCS]](#AAPCS), which states that the
1149
+ caller is responsible for zero- or sign-extending arguments of integral
1150
+ Fundamental Data Types smaller than a word to 4 bytes. An Entry function must
1151
+ not assume that callers follow this rule, that is, it cannot presume that
1152
+ integral parameters will have been zero- or sign-extended to 4 bytes. For
1153
+ example, an attacker might create code that passes arguments out of their
1154
+ declared type's range in an attempt to cause out-of-bounds memory accesses.
1142
1155
1143
1156
<span id="requirement-47" class="requirement-box"></span>
1157
+ > A compiler generating code for an entry function must, for each parameter
1158
+ > that is an integral Fundamental Data Type smaller than a word, make no
1159
+ > assumptions about the value of the padding bits, even when the value of
1160
+ > those bits are defined by the AAPCS.
1161
+
1162
+ A possible implementation is shown below:
1163
+
1164
+ ```c
1165
+ int array[256];
1166
+
1167
+ __attribute__((cmse_nonsecure_entry))
1168
+ int func(unsigned char idx) {
1169
+ return array[idx];
1170
+ }
1171
+ ```
1172
+
1173
+ ``` c
1174
+ __acle_se_func:
1175
+ func:
1176
+ ...
1177
+ @ narrow ' idx' to 8 bits before first use
1178
+ uxtb r0, r0
1179
+ movw r1, :lower16:array
1180
+ movt r1, :upper16:array
1181
+ ldr.w r0, [r1, r0, lsl #2 ]
1182
+ ...
1183
+ bxns lr
1184
+ ```
1185
+
1186
+ We recommend that function parameters with integral types smaller than 4
1187
+ bytes should be avoided. This recommendation extends to underlying types of
1188
+ ` enum ` used as parameters.
1189
+
1190
+ ### Return from an entry function
1191
+
1192
+ <span id =" requirement-48 " class =" requirement-box " ></span >
1144
1193
1145
1194
> An entry function must use the BXNS instruction to return to its
1146
1195
> non-secure caller.
@@ -1153,7 +1202,7 @@ To prevent information leakage when an entry function returns, you must clear th
1153
1202
registers that contain secret information
1154
1203
([ Information leakage] ( #information-leakage ) ).
1155
1204
1156
- <span id="requirement-48 " class="requirement-box"></span>
1205
+ <span id =" requirement-49 " class =" requirement-box " ></span >
1157
1206
1158
1207
> The code sequence directly preceding the ` BXNS ` instruction that transitions
1159
1208
> to non-secure code must:
@@ -1186,7 +1235,7 @@ difficult.
1186
1235
An entry function can be called from secure or non-secure state. Software needs
1187
1236
to distinguish between these cases.
1188
1237
1189
- <span id="requirement-49 " class="requirement-box"></span>
1238
+ <span id =" requirement-50 " class =" requirement-box " ></span >
1190
1239
1191
1240
> The following intrinsic function must be provided if bit 1 of macro
1192
1241
> ` __ARM_FEATURE_CMSE ` is set:
@@ -1212,12 +1261,12 @@ only happen via function pointers. This is a consequence of separating
1212
1261
secure and non-secure code into separate executable files as described
1213
1262
in [ Executable files] ( #executable-files ) .
1214
1263
1215
- <span id="requirement-50 " class="requirement-box"></span>
1264
+ <span id =" requirement-51 " class =" requirement-box " ></span >
1216
1265
1217
1266
> A non-secure function type must be declared using the function attribute
1218
1267
> ` __attribute__((cmse_nonsecure_call)) ` .
1219
1268
1220
- <span id="requirement-51 " class="requirement-box"></span>
1269
+ <span id =" requirement-52 " class =" requirement-box " ></span >
1221
1270
1222
1271
> A non-secure function type must only be used as a base type of a pointer.
1223
1272
@@ -1226,7 +1275,7 @@ executable file only contains secure function definitions.
1226
1275
1227
1276
### Performing a call
1228
1277
1229
- <span id="requirement-52 " class="requirement-box"></span>
1278
+ <span id =" requirement-53 " class =" requirement-box " ></span >
1230
1279
1231
1280
> A function call through a pointer with a non-secure function type as its
1232
1281
> base type must switch to the non-secure state.
@@ -1245,7 +1294,7 @@ that contain values that are used after the non-secure function call
1245
1294
must be restored after the call returns. Secure code cannot depend on
1246
1295
the non-secure state to restore these registers.
1247
1296
1248
- <span id="requirement-53 " class="requirement-box"></span>
1297
+ <span id =" requirement-54 " class =" requirement-box " ></span >
1249
1298
1250
1299
> The code sequence directly preceding the ` BLXNS ` instruction that
1251
1300
> transitions to non-secure code must:
@@ -1263,7 +1312,7 @@ the non-secure state to restore these registers.
1263
1312
A toolchain could provide you with the means to specify that some
1264
1313
types of variables never hold secret information.
1265
1314
1266
- <span id="requirement-54 " class="requirement-box"></span>
1315
+ <span id =" requirement-55 " class =" requirement-box " ></span >
1267
1316
1268
1317
> When the non-secure function call returns, caller- and callee-saved
1269
1318
> registers saved before the call must be restored. This includes bits [ 27:0]
@@ -1290,7 +1339,7 @@ usage is required according to [[AAPCS]](#AAPCS), the non-secure state expects
1290
1339
the arguments on the non-secure stack and writes the return value to non-secure
1291
1340
memory.
1292
1341
1293
- <span id="requirement-55 " class="requirement-box"></span>
1342
+ <span id =" requirement-56 " class =" requirement-box " ></span >
1294
1343
1295
1344
> To avoid using the non-secure stack, a toolchain may constrain the
1296
1345
> following, for a non-secure function type:
@@ -1299,7 +1348,7 @@ memory.
1299
1348
> * The type of each parameter.
1300
1349
> * The return type.
1301
1350
1302
- <span id="requirement-56 " class="requirement-box"></span>
1351
+ <span id =" requirement-57 " class =" requirement-box " ></span >
1303
1352
1304
1353
> A compiler compiling a call to a non-secure function must do either of the
1305
1354
> following:
@@ -1335,6 +1384,51 @@ The stack usage during a non-secure function call is shown in figure
1335
1384
1336
1385
![ <span id =" figure6 " class =" citation-label " >** Caller's stack frame of a non-secure function call** </span >] ( stack-frame-non-secure.svg )
1337
1386
1387
+ The return of values from Non-secure function calls follows the
1388
+ [[ AAPCS]] ( #AAPCS ) , which states that the callee is responsible for zero- or
1389
+ sign-extending return values of integral Fundamental Data Types smaller than a
1390
+ word to 4 bytes. A Secure function must not assume that Non-secure callees
1391
+ follow this rule, that is, it cannot presume that integral returned values will
1392
+ have been zero- or sign-extended to 4 bytes. For example, an attacker might
1393
+ create code that returns values out of their declared type's range in an
1394
+ attempt to cause out-of-bounds memory accesses.
1395
+
1396
+ <span id =" requirement-58 " class =" requirement-box " ></span >
1397
+ > A compiler generating code for a Non-secure function call must, for each
1398
+ > returned value that is an integral Fundamental Data Type smaller than a word,
1399
+ > make no assumptions about the value of the padding bits, even when the value
1400
+ > of those bits are defined by the AAPCS.
1401
+
1402
+ A possible implementation is shown below:
1403
+
1404
+ ``` c
1405
+ __attribute__ ((cmse_nonsecure_call))
1406
+ unsigned short (* nonsecurefunc)(void);
1407
+
1408
+ void securefunc(int * array) {
1409
+ unsigned short idx = nonsecurefunc();
1410
+ print(array[ idx] );
1411
+ }
1412
+ ```
1413
+
1414
+ ```c
1415
+ securefunc:
1416
+ ...
1417
+ @ r1 has the address of 'nonsecurefunc'
1418
+ @ r2 has 'array'
1419
+ @ non-secure function call
1420
+ blxns r1
1421
+ @ narrow 'idx' (returned value in r0) to a 16-bit value
1422
+ uxth r0, r0
1423
+ ldr.w r0, [r2, r0, lsl #2]
1424
+ bl print
1425
+ ...
1426
+ ```
1427
+
1428
+ We recommend that function return values with integral types smaller than 4
1429
+ bytes should be avoided. This recommendation extends to underlying types of
1430
+ ` enum ` used as return values.
1431
+
1338
1432
## Non-secure function pointer
1339
1433
1340
1434
A function pointer that has its LSB unset is a non-secure function
@@ -1399,7 +1493,7 @@ void call_callback(void) {
1399
1493
This is just an optimisation technique and hence it is not required for the
1400
1494
correct usage of non-secure function pointers.
1401
1495
1402
- <span id="requirement-57 " class="requirement-box"></span>
1496
+ <span id =" requirement-59 " class =" requirement-box " ></span >
1403
1497
1404
1498
> The following intrinsics are defined if bit 1 of macro
1405
1499
> ` __ARM_FEATURE_CMSE ` is set:
@@ -1428,12 +1522,12 @@ A non-secure callable function is a function that is expected to be placed in an
1428
1522
NSC region. Its functionality is identical to an entry function, but instead of
1429
1523
a secure gateway veneer the function starts with the ` SG ` instruction.
1430
1524
1431
- <span id="requirement-58 " class="requirement-box"></span>
1525
+ <span id =" requirement-60 " class =" requirement-box " ></span >
1432
1526
1433
1527
> A non-secure callable function must be declared by using the attribute
1434
1528
> ` __attribute__((cmse_nonsecure_callable)) ` on a function declaration.
1435
1529
1436
- <span id="requirement-59 " class="requirement-box"></span>
1530
+ <span id =" requirement-61 " class =" requirement-box " ></span >
1437
1531
1438
1532
> A non-secure callable function is identical to an entry function except that:
1439
1533
>
@@ -1449,7 +1543,7 @@ Toolchain support is needed to prevent inadvertent secure gateways
1449
1543
from occurring ([ Inadverted secure
1450
1544
gataway] ( #inadvertent-secure-gateway ) ).
1451
1545
1452
- <span id="requirement-60 " class="requirement-box"></span>
1546
+ <span id =" requirement-62 " class =" requirement-box " ></span >
1453
1547
1454
1548
> A toolchain must provide a way for the programmer to guarantee that a
1455
1549
> non-secure callable function does not contain an inadvertent ` SG ` instruction
@@ -1465,7 +1559,7 @@ non-secure state, but cannot be called by the non-secure state. An example use
1465
1559
would be to provide tail-calls from an entry function to non-secure returning
1466
1560
functions.
1467
1561
1468
- <span id="requirement-61 " class="requirement-box"></span>
1562
+ <span id =" requirement-63 " class =" requirement-box " ></span >
1469
1563
1470
1564
> A non-secure returning function must be declared by using the attribute
1471
1565
> ` __attribute__((cmse_nonsecure_return)) ` on a function declaration.
0 commit comments