Skip to content

Commit c0e1394

Browse files
committed
PIR: illustrations of PIR structure
1 parent 6239d00 commit c0e1394

15 files changed

+310
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
## Libcrypto: crypto/asn1/a_enum.c: ASN1_ENUMERATED_get
2+
3+
### Predicated: 1
4+
5+
#### source code fragment:
6+
7+
```
8+
i=a->type;
9+
if (i == V_ASN1_NEG_ENUMERATED)
10+
neg=1;
11+
```
12+
13+
#### CodeHawk annotated assembly of basic block:
14+
15+
```
16+
0xd4ba4 LDR R2, [R0,#0x4] R2 := R0_in[4]_in (C: __pderef_R0_in.type_in)
17+
0xd4ba8 LDR R3, 0xd4c2c R3 := 0x10a (C: 0x10a) (addr: 0xd4c2c; C: 0xd4c2c)
18+
0xd4bac CMP R2, R3 compare R2 and R3 ((R0_in[4]_in - 0x10a)) (C: (__pderef_R0_in.type_in - 0x10a))
19+
0xd4bb0 MOVEQ R4, #1 if (R0_in[4]_in == 0x10a)(C: (__pderef_R0_in.type_in == 0x10a)) then R4 := 0x1 (C: 0x1)
20+
0xd4bb4 BEQ 0xd4bd0 if (__pderef_R0_in.type_in == 0x10a) then goto 0xd4bd0
21+
```
22+
23+
#### CodeHawk lifting:
24+
25+
if ((a->type == 266)) {
26+
neg = 1; // 0xd4bb0, MOV
27+
} // if
28+
29+
30+
#### High-level PIR for if statement:
31+
32+
The if-statement node is annotated with the property predicated:1, indicating that this
33+
if statement was created for a single predicated instruction, and both the single
34+
instruction in the then block and the condition have associated address 0x4bb0.
35+
36+
![pirview_d4b98_stmt97_high_level](pirview_d4b98_stmt97.png)
37+
38+
39+
### Predicated: 2
40+
41+
The same function also contains an example of the combination of two consecutive
42+
predicated instructions representing the source code fragment:
43+
44+
#### source code fragment
45+
46+
47+
48+
![pirview_d4b98_stmt114_high_level](pirview_d4b98_stmt114.png)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
## Libcrypto: crypto/asn1/ameth_lib.c: ameth_cmp
2+
3+
#### source code:
4+
5+
```
6+
static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
7+
const EVP_PKEY_ASN1_METHOD * const *b)
8+
{
9+
return ((*a)->pkey_id - (*b)->pkey_id);
10+
}
11+
```
12+
13+
#### CodeHawk annotated assembly:
14+
15+
```
16+
int (struct evp_pkey_asn1_method_st * * a, struct evp_pkey_asn1_method_st * * b)
17+
18+
--------------------------------------------------------------------------------
19+
0xe26e4 LDR R3, [R0] R3 := R0_in[0]_in (C: __pderef_R0_in[<[0]>]_in) (addr: a; C: a)
20+
0xe26e8 LDR R2, [R1] R2 := R1_in[0]_in (C: __pderef_R1_in[<[0]>]_in) (addr: b; C: b)
21+
0xe26ec LDR R1, [R3] R1 := R0_in[0]_in[0]_in (C: __pderef___pderef_R0_in[<[0]>]_in.pkey_id_in)
22+
0xe26f0 LDR R0, [R2] R0 := R1_in[0]_in[0]_in (C: __pderef___pderef_R1_in[<[0]>]_in.pkey_id_in)
23+
0xe26f4 RSB R0, R0, R1 R0 := (R1 - R0) (= (R0_in[0]_in[0]_in - R1_in[0]_in[0]_in)) (C: (__pderef___pderef_R0_in[<[0]>]_in.pkey_id_in - __pderef___pderef_R1_in[<[0]>]_in.pkey_id_in))
24+
0xe26f8 BX LR return (R0_in[0]_in[0]_in - R1_in[0]_in[0]_in) (C: (__pderef___pderef_R0_in[<[0]>]_in.pkey_id_in - __pderef___pderef_R1_in[<[0]>]_in.pkey_id_in))
25+
--------------------------------------------------------------------------------
26+
```
27+
28+
#### CodeHawk lifting:
29+
30+
```
31+
int ameth_cmp(struct evp_pkey_asn1_method_st * * a, struct evp_pkey_asn1_method_st * * b) {
32+
33+
return (a[0]->pkey_id - b[0]->pkey_id);
34+
}
35+
```
36+
37+
#### High-level PIR
38+
39+
The high-level PIR has, like the original source code, just one statement, the
40+
return statement, with a return expression. The lval-expressions in the return
41+
expressions are connected to the instructions that define them via the
42+
reaching definitions.
43+
44+
![pirview_e26e4_high_level](./pirview_e26e4.png)
45+
46+
47+
#### Low-level PIR
48+
49+
The low-level PIR includes the full control-flow graph with all its instructions,
50+
without any high-level control flow constructs.
51+
52+
![pirview_e26e5_low_level](./pirview_e26e4_low.png)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
## Libcrypto: crypto/asn1/ameth_lib.c: EVP_PKEY_get0_asn1
2+
3+
#### source code
4+
5+
```
6+
const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
7+
{
8+
return pkey->ameth;
9+
}
10+
```
11+
12+
13+
#### CodeHawk annotated assembly:
14+
15+
```
16+
struct evp_pkey_asn1_method_st * (struct evp_pkey_st * pkey)
17+
18+
--------------------------------------------------------------------------------
19+
0xe277c LDR R0, [R0,#0xc] R0 := R0_in[12]_in (C: __pderef_R0_in.ameth_in)
20+
0xe2780 BX LR return R0_in[12]_in (C: __pderef_R0_in.ameth_in)
21+
--------------------------------------------------------------------------------
22+
```
23+
24+
#### CodeHawk lifting:
25+
26+
```
27+
struct evp_pkey_asn1_method_st * EVP_PKEY_get0_asn1(struct evp_pkey_st * pkey) {
28+
29+
return pkey->ameth;
30+
}
31+
```
32+
33+
#### High-level PIR
34+
35+
![pirview_277c_high_level](pirview_e277c.png)
36+
37+
38+
#### Low-level PIR
39+
40+
![pirview_277c_low_level](pirview_e277c_low.png)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
## Libcrypto: crypto/asn1/ameth_lib.c: EVP_PKEY_ans1_set_private
2+
3+
#### source code
4+
5+
```
6+
void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
7+
int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
8+
int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
9+
int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
10+
ASN1_PCTX *pctx))
11+
{
12+
ameth->priv_decode = priv_decode;
13+
ameth->priv_encode = priv_encode;
14+
ameth->priv_print = priv_print;
15+
}
16+
```
17+
18+
#### CodeHawk annotated assembly code
19+
20+
```
21+
void (struct evp_pkey_asn1_method_st * ameth, int__(struct pkcs8_priv_key_info_st * p8inf, struct evp_pkey_st * pk) * priv_decode, int__(struct evp_pkey_st * pk, struct pkcs8_priv_key_info_st * p8) * priv_encode, int__(struct asn1_pctx_st * pctx, int indent, struct evp_pkey_st * pkey, struct bio_st * out) * priv_print)
22+
23+
--------------------------------------------------------------------------------
24+
0xe2860 STR R3, [R0,#0x2c] R0_in[44] := priv_print (C: __pderef_R0_in.priv_print := priv_print)
25+
0xe2864 STR R1, [R0,#0x24] R0_in[36] := priv_decode (C: __pderef_R0_in.priv_decode := priv_decode)
26+
0xe2868 STR R2, [R0,#0x28] R0_in[40] := priv_encode (C: __pderef_R0_in.priv_encode := priv_encode)
27+
0xe286c BX LR return ameth (C: ameth)
28+
--------------------------------------------------------------------------------
29+
```
30+
31+
#### CodeHawk lifting
32+
33+
```
34+
void EVP_PKEY_asn1_set_private(struct evp_pkey_asn1_method_st * ameth,
35+
int (*priv_decode)(struct evp_pkey_st * pk, struct pkcs8_priv_key_info_st * p8inf),
36+
int (*priv_encode)(struct pkcs8_priv_key_info_st * p8, struct evp_pkey_st * pk),
37+
int (*priv_print)(struct bio_st * out, struct evp_pkey_st * pkey,
38+
int indent, struct asn1_pctx_st * pctx)) {
39+
40+
ameth->priv_print = priv_print; // 0xe2860, STR
41+
ameth->priv_decode = priv_decode; // 0xe2864, STR
42+
ameth->priv_encode = priv_encode; // 0xe2868, STR
43+
return;
44+
}
45+
46+
```
47+
48+
#### High-level PIR
49+
50+
![pirview_2860_high_level](./pirview_e2860.png)
51+
52+
53+
#### Low-level PIR
54+
55+
![pirview_2860_low_level](./pirview_e2860_low.png)
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
## Libcrypto: crypto/asn1/ameth_lib.c: EVP_PKEY_asn1_free
2+
3+
#### source code
4+
5+
```
6+
void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
7+
{
8+
if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC))
9+
{
10+
if (ameth->pem_str)
11+
OPENSSL_free(ameth->pem_str);
12+
if (ameth->info)
13+
OPENSSL_free(ameth->info);
14+
OPENSSL_free(ameth);
15+
}
16+
}
17+
```
18+
19+
#### CodeHawk annotated assembly:
20+
21+
```
22+
void (struct evp_pkey_asn1_method_st * ameth)
23+
24+
--------------------------------------------------------------------------------
25+
0xe28a8 PUSH {R4,LR} SP := (SP_in - 0x8); var_0008 := R4_in; var_0004 := LR_in
26+
0xe28ac SUBS R4, R0, #0 R4 := (R0 - 0x0) (= ameth) (C: ameth)
27+
0xe28b0 POPEQ {R4,PC} if (ameth == 0x0)(C: (ameth == 0x0)) then SP := SP_in; R4 := R4_in; PC := LR_in; return 0x0 (C: 0x0)
28+
--------------------------------------------------------------------------------
29+
0xe28b4 LDR R3, [R4,#0x8] R3 := R0_in[8]_in (C: __pderef_R0_in.pkey_flags_in)
30+
0xe28b8 TST R3, #2 compare 0x2 and R3 ((R3 & 0x2))
31+
0xe28bc POPEQ {R4,PC} if ((R0_in[8]_in & 0x2) == 0x0)(C: ((__pderef_R0_in.pkey_flags_in & 0x2) == 0x0)) then SP := SP_in; R4 := R4_in; PC := LR_in; return ameth (C: ameth)
32+
--------------------------------------------------------------------------------
33+
0xe28c0 LDR R0, [R4,#0xc] R0 := R0_in[12]_in (C: __pderef_R0_in.pem_str_in)
34+
0xe28c4 CMP R0, #0 compare R0 and 0x0 (R0_in[12]_in) (C: __pderef_R0_in.pem_str_in)
35+
0xe28c8 BEQ 0xe28d0 if (__pderef_R0_in.pem_str_in == 0x0) then goto 0xe28d0
36+
--------------------------------------------------------------------------------
37+
0xe28cc BL 0x3be80 call CRYPTO_free(R0_in[12]_in) (C: (__pderef_R0_in.pem_str_in))
38+
--------------------------------------------------------------------------------
39+
0xe28d0 LDR R0, [R4,#0x10] R0 := R0_in[16]_in (C: __pderef_R0_in.info_in)
40+
0xe28d4 CMP R0, #0 compare R0 and 0x0 (R0_in[16]_in) (C: __pderef_R0_in.info_in)
41+
0xe28d8 BEQ 0xe28e0 if (__pderef_R0_in.info_in == 0x0) then goto 0xe28e0
42+
--------------------------------------------------------------------------------
43+
0xe28dc BL 0x3be80 call CRYPTO_free(R0_in[16]_in) (C: (__pderef_R0_in.info_in))
44+
--------------------------------------------------------------------------------
45+
0xe28e0 MOV R0, R4 R0 := ameth (C: ameth)
46+
0xe28e4 POP {R4,LR} SP := SP_in; R4 := R4_in; LR := LR_in
47+
0xe28e8 B 0x3be80 call CRYPTO_free(ameth) (C: (ameth))
48+
--------------------------------------------------------------------------------
49+
```
50+
51+
#### CodeHawk lifting:
52+
53+
```
54+
void EVP_PKEY_asn1_free(struct evp_pkey_asn1_method_st * ameth) {
55+
56+
if ((ameth == 0)) {
57+
return;
58+
} // if
59+
if (((ameth->pkey_flags & 2) == 0)) {
60+
return;
61+
} // if
62+
if ((ameth->pem_str != 0)) {
63+
CRYPTO_free(ameth->pem_str); // 0xe28cc, BL
64+
} // if
65+
if ((ameth->info != 0)) {
66+
CRYPTO_free(ameth->info); // 0xe28dc, BL
67+
} // if
68+
CRYPTO_free(ameth); // 0xe28e8, BL
69+
return;
70+
}
71+
```
72+
73+
#### High-level PIR
74+
75+
The PIR visualization below shows the four if statements contained in
76+
this function (only the statement/instruction skeleton is shown here
77+
to keep the size of the graph manageable). The first two if statements
78+
originate from a predicated instruction (they currently do not have
79+
a reference to the 'branch' instruction). The last two if statements
80+
are regular branches constructed from conditional jumps.
81+
82+
![pirview_28a8_high_level](pirview_e28a8.png)

chb/ast/doc/pirexamples/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# PIR ILLUSTRATED
2+
3+
## A few small functions
4+
5+
- [crypto/asn1/ameth_lib.c: EVP_PKEY_get0_asn1](6f891f20_e277c.md):
6+
A small function that returns the value of a field.
7+
8+
- [crypto/asn1/ameth_lib.c: ameth_cmp](6f891f20_e26e4.md):
9+
Another small function that returns a slightly more complex expression.
10+
11+
- [crypto/asn1/ameth_lib.c: EVP_PKEY_asn1_set_private](6f891f20_e2860.md):
12+
A small void-returning function with three updates.
13+
14+
15+
## Predicated Instructions
16+
17+
ARM allows conditional execution of instructions using condition codes
18+
that are part of almost all instruction types. Predicated instructions
19+
are handled in a few different ways in the lifting to C, depending on
20+
their context and purpose.
21+
22+
The first option is to create full control flow in the control flow
23+
graph. This approach is followed, for example, when a return instruction
24+
(usually POP) is predicated. The following function provides an example:
25+
26+
- [crypto/asn1/ameth_lib.c: EVP_PKEY_asn1_free](6f891f20_e28a8.md):
27+
28+
The second option is to create light-weight control flow, which is not
29+
present in the cfg, but is introduced in the process of lifting by
30+
breaking up a basic block into fragments and inserting if statements
31+
accordingly. This approach is illustrated in the following function:
32+
33+
- [crypto/asn1/a_enum.c: ASN1_ENUMERATED_get](6f891f20_d4b98.md):
113 KB
Loading
71.3 KB
Loading
84.2 KB
Loading
293 KB
Loading

0 commit comments

Comments
 (0)