17 Aug 2015

feedPlanet Maemo

Android - Using Crypto extensions

I had some problems compiling ASM code as part of an Android kernel module.

As part of my system, I need to encrypt/decrypt data inside the kernel and I decided to use AES CBC with 128 bits keys. I am also using a Nexus 9 (arm64 v8), which means that I have access to crypto extensions, including instructions for AES operations :-)

Considering this scenario, I implemented 3 options (of course, I picked the most efficient one at the end):

  1. A "standard" AES CBC implementation in C (the worst performance);
  2. The Linux kernel Crypto lib with crypto extensions set to ON (good performance and very easy to use);
  3. The AES CBC asm implementation from the OpenSSL lib (good performance and it took me extra time to integrate it into my code);

At the end, I took the option #03. Both #02 and #03 have good performance, but #03 is slightly better.

Let's discuss #02 and #03 in this post.

As the very first step, check if your kernel has the proper options enabled for the crypto extension usage. The following ones should be set to "y":

CONFIG_CRYPTO_HW
CONFIG_ARM64_CRYPTO
CONFIG_CRYPTO_AES_ARM64_CE
CONFIG_CRYPTO_AES_ARM64_CE_CCM
CONFIG_CRYPTO_AES_ARM64_CE_BLK

The Crypto lib

The Linux kernel provides the Crypto library, with several cryptography operations, such as AES, including different block/streams ciphers. The following code use AES 128-bits CBC, and a 0-ed IV (don't do that!)

static int pc_aes_encrypt_kernel(const void *key, int key_len,
void *dst, size_t *dst_len,
const void *src, size_t src_len)
{
struct crypto_blkcipher *blkcipher = NULL;
char *cipher = "__cbc-aes-ce";
char iv[AES_BLOCK_SIZE];
char *charkey = (unsigned char *) key;

unsigned int ivsize = 0;
char *scratchpad_in = NULL, *scratchpad_out = NULL;
struct scatterlist sg_in, sg_out;
struct blkcipher_desc desc;
int ret = -EFAULT;
int len = ((int)(src_len/16) + 1) * 16;

memset(iv, 0x00, AES_BLOCK_SIZE); // set the iv to a proper value!!

blkcipher = crypto_alloc_blkcipher(cipher, 0, 0);
if (IS_ERR(blkcipher)) {
PC_LOGV("could not allocate blkcipher handle for %s\n", cipher);
return -PTR_ERR(blkcipher);
}

if (crypto_blkcipher_setkey(blkcipher, charkey, key_len)) {
PC_LOGV("key could not be set\n");
ret = -EAGAIN;
goto out;
}

ivsize = crypto_blkcipher_ivsize(blkcipher);
if (ivsize) {
if (ivsize != AES_BLOCK_SIZE)
PC_LOGV("IV length differs from expected length. It should be : %d\n",ivsize);
crypto_blkcipher_set_iv(blkcipher, iv, ivsize);
}

scratchpad_in = kmalloc(src_len, GFP_KERNEL);
if (!scratchpad_in) {
PC_LOGV("could not allocate scratchpad_in for %s\n", cipher);
goto out;
}

scratchpad_out = kmalloc(len, GFP_KERNEL);
if (!scratchpad_out) {
PC_LOGV("could not allocate scratchpad_in for %s\n", cipher);
goto out;
}

memcpy(scratchpad_in,src,src_len);

desc.flags = 0;
desc.tfm = blkcipher;
sg_init_one(&sg_in, scratchpad_in, src_len);
sg_init_one(&sg_out, scratchpad_out, len);

crypto_blkcipher_encrypt(&desc, &sg_out, &sg_in, src_len);

// for decryption, use the following
// crypto_blkcipher_decrypt(&desc, &sg_out, &sg_in, src_len);

memcpy(dst,scratchpad_out,sg_out.length);

*dst_len = sg_out.length;

ret = 0;
goto out;

out:
if (blkcipher)
crypto_free_blkcipher(blkcipher);
if (scratchpad_out)
kzfree(scratchpad_out);
if (scratchpad_in)
kzfree(scratchpad_in);

return ret;

}


For decryption, you can use the same code, but use the function crypto_blkcipher_decrypt instead.

Integrating a *.S file as part if your module built process

As said, I used an existing implementation from OpenSSL, which uses the crypto extensions of arm64-v8. I only had to change the "includes" of the asm file. In addition, I included the object file into my Makefile, like this:


pc_module-objs := ...
src/pc_utility.o src/asm/aesv8-armx-64.o \
src/crypto/aes.o src/crypto/crypto.o


However, I had some problems with different asm files that I was testing. For example, for the OpenSSL library, some of them will not compile if you use GCC 4.8/4.9. The point is that they use a different architectural syntax (Apple) and you'll see several "Error: unknown mnemonic" error messages.

So, you can use LLVM to compile the asm files with the Apple architectural syntax. LLVM is available in the Android NDK. Then, you can copy the *.o files into your code and build your project. The symbols should match as a charm.

The following code shows the usage of the functions defined in the file aesv8-armx-64.S (available into the folder /external/openssl/)


static int pc_aes_encrypt_hw(const void *key, int key_len,
void *dst, size_t *dst_len,
const void *src, size_t src_len)
{
AES_KEY enc_key;

unsigned char enc_out[src_len];
unsigned char iv[AES_BLOCK_SIZE];
unsigned char *aes_input = (unsigned char *) src;
unsigned char *aes_key = (unsigned char *) key;

memset(iv, 0x00, AES_BLOCK_SIZE);

HWAES_set_encrypt_key(aes_key, key_len*8, &enc_key);
HWAES_cbc_encrypt(aes_input, enc_out, src_len, &enc_key, iv, AES_ENCRYPT);

*dst_len = src_len;
memcpy(dst,&enc_out[0],src_len);

return 0;
}

static int pc_aes_decrypt_hw(const void *key, int key_len,
void *dst, size_t *dst_len,
const void *src, size_t src_len)
{
AES_KEY dec_key;

unsigned char iv[AES_BLOCK_SIZE];
unsigned char dec_out[src_len];
unsigned char *aes_input = (unsigned char *) src;
unsigned char *aes_key = (unsigned char *) key;

memset(iv, 0x00, AES_BLOCK_SIZE);

HWAES_set_decrypt_key(aes_key, key_len*8, &dec_key);
HWAES_cbc_encrypt(aes_input, dec_out, src_len, &dec_key, iv, AES_DECRYPT);

*dst_len = src_len;
memcpy(dst,&dec_out[0],src_len);

return 0;
}



The functions HWAES_set_encrypt_key, HWAES_set_decrypt_key, HWAES_cbc_encrypt and HWAES_cbc_decrypt are implemented in a asm file (aesv8-armx-64.S) and defined in a header file (aes_cbc.h). Again, I used AES 128-bits CBC, with 0-ed IV (don't do that!).


0 Add to favourites0 Bury

17 Aug 2015 4:28pm GMT

07 Aug 2015

feedPlanet Maemo

Microsoft Education Delivery


We spent last year designing and creating MED so it was nice to find this video created by Microsoft explaining what it is and how it works
0 Add to favourites0 Bury

07 Aug 2015 5:06pm GMT

05 Aug 2015

feedPlanet Maemo

Converting a Ubuntu and Windows dual-boot installation to UEFI

UEFI is the successor to BIOS for communicating with the Firmware on your Mainboard.
While the first BIOS was released with the IBM-PC in 1981, the first UEFI version (EFI 2.0) was released 25 years later in 2006 building upon the lessons learned in that timespan. So UEFI is without any doubt the more modern solution.

The user-visible advantages of using UEFI instead of BIOS are

You could reinstall both Windows and Ubuntu to get UEFI. However it is also possible to convert existing installations of both on the fly - without the backup/ restore cycle. You should still do a backup in case something goes wrong though.

Prerequisites

Only the 64bit Versions of Windows support UEFI. Therefore this guide assumes that you run the 64bit versions of both Windows and Ubuntu.

Furthermore verify the following items before you continue - otherwise you will not be able to finish the conversion. Use GParted in case you have not enough space before the first or after the last partition.

to test that the sticks are indeed UEFI compatible, try booting them with CSM Mode disabled in your BIOS.

Convert the drive to GPT

UEFI requires a GUID Partition Table (GPT), so first we need to convert from MBR to GPT.

After this step you will not be able to boot your system any more. So make sure you have the Ubuntu USB drive ready.

We will use gdisk to perform the conversion as following:

sudo gdisk /dev/sdX
Command (? for help): w

where sdX is your system drive (e.g. sda)

Convert Windows to UEFI

Now boot your Windows USB drive and enter the command prompt as described in this Microsoft Technet article at step 6.

Continue with the following steps from the Article. Note that we have skipped steps 1-4 as we used Ubuntu to convert the disk to GPT.

We have now created a EFI partition, a new EFI compatible Windows System Partition and we have installed the Windows Bootloader to the EFI partition. Your Windows installation should now start again.
At this point you could also perform an upgrade to Windows 10, as the upgrade would erase grub from the EFI partition anyway.

Next we are going to install grub to the EFI partition and make it manage the boot.

Enter a Ubuntu chroot

As we can not directly boot our Ubuntu installation, we will instead boot from the Ubuntu USB drive and the switch to the installed Ubuntu.
To do the switch we have to setup and enter a chroot as following

sudo mount /dev/sdXY /mnt 
sudo mount /dev/sdX1 /mnt/boot/efi 
sudo mount -o bind /dev /mnt/dev
sudo mount -o bind /sys /mnt/sys
sudo mount -t proc /proc /mnt/proc
sudo cp /proc/mounts /mnt/etc/mtab
sudo cp /etc/resolv.conf /mnt/etc/resolv.conf
sudo chroot /mnt

where sdXY is the partition where your Ubuntu system is installed (e.g. sda5)

Convert Ubuntu to UEFI

Inside your Ubuntu Installation we have to replace grub for BIOS (aka grub-pc) with grub for UEFI (aka grub-efi) as:

sudo apt-get --reinstall install grub-common grub-efi-amd64 os-prober

this would be enough to get the system booting again, however we also aim for secure boot so we also need to install the following:

sudo apt-get install shim-signed grub-efi-amd64-signed linux-signed-generic

This installs signatures for grub and the kernel which are used to verify the integrity of these at boot. Furthermore we install shim, which is a passthrough bootloader that translates from the Microsoft signatures on you mainboard to the signatures by Canonical used to sign grub and the kernel (see this for details).

Next we finally install grub to the EFI partition by:

sudo grub-install --uefi-secure-boot /dev/sdX
sudo update-grub

where sdX is again your system drive (e.g. sda).

Now you can enable secure boot in your BIOS and benefit. Note that some BIOS implementations additionaly require you to select the trusted signatures. Look out for an option called "Install Default Secure Boot keys" or similar to select the Microsoft signatures.

0 Add to favourites0 Bury

05 Aug 2015 2:13pm GMT

02 Aug 2015

feedPlanet Maemo

Re-Announcement of the Q2 2015 Community Council Election

Dear friends and Maemoans, as it happens we did not get enough confirmed candidates in the set nomination period, so according to the Council Election Rules we need to extend the nomination period by 4 weeks.

This will push all dates one month to future. The new schedule of the voting is as follows:

Currently we have 5 confirmed candidates. (endsormeans, juiceme, reinob, Win7Mac, peterleinchen)

On behalf of the outgoing community council,

Jussi Ohenoja

0 Add to favourites0 Bury

02 Aug 2015 10:00pm GMT

2015-07-28 Council Meeting Minutes

Meeting held 2015-07-28 on FreeNode, channel #maemo-meeting (logs)

Attending: Jussi Ohenoja (juiceme), Peter Leinchen (peterleinchen), Gido Griese (Win7Mac), Paul Carlin (endsormeans)

Partial: Ruediger Schiller (chem|st)

Absent: Oksana Tkachenko (Oksana/Wikiwide), William McBee (gerbick), Alexander Kozhevnikov (MentalistTraceur)

Summary of topics (ordered by discussion):


(Topic Ongoing Council Elections):

(Topic TM donation status):


Action Items:
  • old items:
    • The selected Code of Conduct (KDE) still needs to be published on TMO.
    • Looking into automatic calculation of election results ...
    • Contacting freemangordon and merlin1991 about auto-builder: CSSU-thumb target, GCC versions?
    • Getting maemo trademark registration (everywhere?) renewed (and transferred to MCeV) by the end of February (or within six months since expiry date).
    • Archiving Ovi/Nokia store, especially for Harmattan.
    • Contacting Daphne Won on Facebook and LinkedIn to get administrator rights on Facebook for a Maemo member to migrate the plugin to v2.0 API and maintain it in the future.
  • new items:

0 Add to favourites0 Bury

02 Aug 2015 8:23pm GMT

01 Aug 2015

feedPlanet Maemo

Gebruik maken van verbanden tussen metadata

Ik beweerde onlangs ergens dat een systeem dat verbanden (waar, wanneer, met wie, waarom) in plaats van louter metadata (titel, datum, auteur, enz.) over content verzamelt een oplossing zou kunnen bieden voor het probleem dat gebruikers van digitale media meer en meer zullen hebben; namelijk dat ze teveel materiaal gaan verzameld hebben om er ooit nog eens iets snel genoeg in terug te vinden.

Ik denk dat verbanden meer gewicht moeten krijgen dan louter de metadata omdat het door middel van verbanden is dat wij mensen in onze hersenen informatie onthouden. Niet door middel van feiten (titel, datum, auteur, enz.) maar wel door middel van verbanden (waar, wanneer, met wie, waarom) .

Ik gaf als hypothetisch voorbeeld dat ik een video wilde vinden die ik gekeken had met Erika toen ik op vakantie was met haar en die zij als super tof had gemarkeerd.

Wat zijn de verbanden die we moeten verzamelen? Dit is een eenvoudig oefeningetje in analyse: gewoon de zelfstandige naamwoorden onderlijnen en het probleem opnieuw uitschrijven:

Dus laat ik deze use-case eens in RDF gieten en oplossen met SPARQL. Dit moeten we verzamelen. Ik schrijf het in pseudo TTL. Bedenk er even bij dat deze ontology helemaal bestaat:

<erika> a Person ; name "Erika" .
<vakantiePlek> a PointOfInterest ; title "De vakantieplek" .
<filmA> a Movie ; lastSeenAt <vakantiePlek> ; sharedWith <erika>; title "The movie" .
<erika> likes <filmA> .

Dit is daarna de SPARQL query:

SELECT ?m { ?v a Movie ; title ?m . ?v lastSeenAt ?p . ?p title ?pt . ?v sharedWith <erika> . <erika> likes ?v . FILTER (?pt LIKE '%vakantieplek%') }

Ik laat het als een oefening aan de lezer om dit naar de ontology Nepomuk om te zetten (volgens mij kan het deze hele use-case aan). En dan kan je dat eens op je N9 of je standaard GNOME desktop testen met de tool tracker-sparql. Wedden dat het werkt. :-)

Het grote probleem is inderdaad de data aquisitie van de verbanden. De query maken is vrij eenvoudig. De ontology vastleggen en afspreken met alle partijen al wat minder. De informatie verzamelen is dé moeilijkheid.

Oh ja. En eens verzameld, de informatie veilig bijhouden zonder dat mijn privacy geschonden wordt. Dat lijkt tegenwoordig gewoonweg onmogelijk. Helaas.

Het is in ieder geval niet nodig dat een supercomputer of zo dit centraal moet oplossen (met AI en heel de gruwelijk complexe hype zooi van vandaag).

Ieder klein toestelletje kan dit soort use-cases zelfstandig oplossen. De bovenstaande inserts en query zijn eenvoudig op te lossen. SQLite doet dit in een paar milliseconden met een gedenormalizeerd schema. Uw fancy hipster NoSQL oplossing waarschijnlijk ook.

Dat is omdat het gewicht van data aquisitie op de verbanden ligt in plaats van op de feiten.

0 Add to favourites0 Bury

01 Aug 2015 2:48pm GMT

23 Jul 2015

feedPlanet Maemo

2015-07-21 Council Meeting Minutes

Meeting held 2015-07-21 on FreeNode, channel #maemo-meeting (logs)

Attending: Jussi Ohenoja (juiceme), Peter Leinchen (peterleinchen)

Partial:

Absent: Oksana Tkachenko (Oksana/Wikiwide), William McBee (gerbick), Alexander Kozhevnikov (MentalistTraceur)

Summary of topics (ordered by discussion):


(Topic TM donation status):

(Topic Referendum and Elections announcement):


Action Items:
  • old items:
    • The selected Code of Conduct (KDE) still needs to be published on TMO.
    • Looking into automatic calculation of election results ...
    • Contacting freemangordon and merlin1991 about auto-builder: CSSU-thumb target, GCC versions?
    • Getting maemo trademark registration (everywhere?) renewed (and transferred to MCeV) by the end of February (or within six months since expiry date).
    • Archiving Ovi/Nokia store, especially for Harmattan.
    • Contacting Daphne Won on Facebook and LinkedIn to get administrator rights on Facebook for a Maemo member to migrate the plugin to v2.0 API and maintain it in the future.
  • new items:

0 Add to favourites0 Bury

23 Jul 2015 7:16pm GMT

19 Jul 2015

feedPlanet Maemo

Referendum 2015

on the roles of Community Council and Maemo e.V.

Referendum 2015
(on the roles of Community Council and Maemo e.V.)

Dear Community,

in order to finalize our move from Hildon Foundation to the Maemo Community e.V. (MC eV), a referendum is called, which is supposed to fix deficiencies in the Council Election Rules as well as in the Articles of Association of MC eV. There will be two options:

- Yes, I accept MC eV Association Rules as our Community Council's Rules and I endorse the amendment of MC eV Articles of Association as described below.

- No, I do want Council rules to stay outside of MC eV and its ruleset and have them as originally described. I'm aware that Council then will have no say in any MC eV or maemo.org matters.

In other words...

…you vote option YES:

Rules around Maemo Community Council are adopted in order to fully incorporate Council as a body of MC eV.

…you vote NO on the referendum:

The original Council election rules will remain as is. Council then will be an interest grouping outside MC eV without a purpose, since there'll be nobody to (officially) adress anymore. Council then will be suspended from MC eV bylaws.

Either way, the referendum means a change of MC eV Articles of Association as well as Association Rules, which can only be done by GA. The referendum basically is an avowal for MC eV, an approval of its bylaws and a mandate for MC eV to change them accordingly.

For those who did not follow the process, here's a short explanation in two parts (together with the affected rules, bylaws paragraphs):



Part 1 - History & Council election rules:

Back in Nokia times, the purpose of Council was to give the community a voice towards Nokia representatives (Community Manager, whatever…). Then Nokia abandoned Maemo, donated servers and sold the rights to maemo.org and Maemo(TM) to Hildon Foundation, a maemo community driven organisation. In the process of this we learned that an US based organisation has its drawbacks/challenges and it was decided to form an entity based in Europe which is a German Registered Association now known as Maemo Community e.V. - instead of having a board assigned to manage the organization, only the association is now accepting regular members which have the final say in any matter. The association's board does handle day to day tasks like minor community requests, funds, buy hardware for our infrastructure, basically pay the bills and do minor steering only. That said, the associations regular members having the final say in any matter, this also applies to rules and regulations and their changes, including but not limited to the Council Election Rules. During the MC eV founding meeting, the existing (unified Maemo Community/HiFo) Council was nominated for the Council of MC eV. The MC eV members voted unanimously "yes" for all existing councilors who accepted the vote. By doing so, Council effectively accepted MC eV Council election rules (and all other other regulations) which were publicized earlier. To have this sanctioned by all of you, we need this referendum.

MC eV Council election rulesdiffer to original Council election rulesin the following points:



Association Rules § 4.1 (Council Elections)

(6)Nominees with a professional interest in Maemo, such as working for Nokia - or any otheracompany involved in Maemo-related software development - must declare their interest when advertising their nomination. Failure to do so may result in the Nokia Community ManagerBoardof Directors, or the outgoing Council, declaring their nomination invalid and so bar them from standing in the current election."

(9)The election date must be publicised at least 1 month4 weeksin advance of the election.

(11) If there are less than 4 candidates when the nominations close, the election can't be held.

a) The nomination period will be extended by 1 month4 weeksand the election postponed similarly.

b) If, after 1 month4 weeks's delay, there are still fewer than 4 candidates; the outgoing council will decide - in conjunction with Hildon FoundationBoard of Directors - about how to proceed. The preferred solution is to encourage more members of the maemo.org community to participate and re-run the election, but all options are open.

(12)Changes to any of the above rules must be approved by a resolution of the Passive Members' Meeting (community referendum) or General Assembly.*

a) Voting in such,will be open to anyone eligible to vote in the respective meeting.

b) The referendum options must be debated for a minimum of 1 month4 weeksprior to the referendum.

c) Referendum voting will be open for the same length of time as the council elections.

* community referendum (aka resolution of the Passive Members' Meeting) is already granted by Articles of Association § 10 and Association Rules § 1.1

Now in order to grant sovereignty over Council election rules to community, the following changes to MC eV Association Rules shall be introduced:

Association Rules § 1.1 (Amendments)

(1) These association rules can be changed or dismissed by the General Assembly.

(2) § 4.1 (Council election rules) of these association rules can be changed or dismissed with a referendum by the Passive Members' Meeting.Changes to theseelection rulesby the GeneralAssembly must be confirmed by a resolution of the passive membersmeeting (referendum). Should the amendment be rejected by the passive membersmeeting, the proposed amendment can be revised and brought again to the vote.

(2) § 4.1 (Vorstandsratswahlen) dieser Vereinsordnung kann durch ein Referendum der passiven Mitgliederversammlung geändert oder aufgehoben werden.Änderungendieser Wahlordnung durch die aktive Mitgliederversammlung müssen durch Beschlussder passiven Mitgliederversammlung bestätigt werden (Referendum).Sollte die Änderung von der passiven Mitgliederversammlung abgelehnt werden, kann der Änderungsvorschlag überarbeitet und erneut zur Abstimmung gebracht werden.

(please see MC eV Orga-chartfor who can actually change what)



Part 2 - Council role & MC eV Bylaws:

MC eV Articles of Association have a drawback which lies within the fact that councils responsibility is not adequately described so far, Council may contradict GA resolutions or even try to "force" Board into anything. Therefore, the following changes to MC eV Articles of Association shall be introduced:

§ 7 (Board of directors)

(5)The Board of Directors executescarries outthe resolutions of the General Assembly and of the Council insofar as this decision jurisdiction is delegated to Council according to the statutes.

(5)Der Vorstand führt die Beschlüsse der aktiven Mitgliederversammlung und der des Vorstandsrats aus, sofern ihm diese Entscheidungshoheit laut Satzung oder Vereinsordnung eingeräumt wird.

§ 8 (Council)

(4)The council has the duty to execute elections of all kinds.The council's duties, rules to announce council meetings, their proceedings and executions of votes are regulated by the Association Rules.

(4) Der Vorstandsrat ist insbesondere für die Durchführung aller Wahlen zuständig.Aufgaben des Vorstandsrats sowieRegelungen zur dessen Arbeit inklusive der Einberufung von Vorstandsratssitzungen, deren Ablauf und die Durchführung von Abstimmungen, wird durch diesind in der Vereinsordnung geregeltfestgelegt.

This outsources the definition of Council responsibility from Articles of Association to Association Rules (which might be altered without the need to register those changes at court, avoiding hassle and fees). Accordingly, a new paragraph will be added to the Association Rules:

§ 3.2 Vorstandsrat (council)

(8) Tasks and competences of the Council are as follows:

(a) Representation of the associated members (garage account) and their interests.

(b) Counseling of the Board of directors in general matters

c) Council is responsible to execute all elections

(8) Aufgaben und Zuständigkeiten des Vorstandsrats sind wie folgt:

(a) Vertretung der assoziierten Mitglieder und ihrer Interessen

(b) Beratung des Vorstands in allgemeinen Belangen

c) Der Vorstandsrat ist für die Durchführung aller Wahlen zuständig

Please note that according to Articles of Association, General Assembly can decide on literally anything, as of

§ 9 (General Assembly)

  1. The General Assembly as the superior decision-making body of the association is by default responsible for all tasks unless certain tasks are delegated to other bodies of the association in accordance with these articles of incorporation.





Coincidence or not, the last paragraph somewhat closes a circle… everybody can have his share of power by simply becoming a member. Get involved yourself instead of just electing representatives (Council).

So in one month the voting booth will open and you can decide on above mentioned changes and if Council will be recognized as a group within the Maemo Community e.V. or not.

0 Add to favourites0 Bury

19 Jul 2015 8:11pm GMT

18 Jul 2015

feedPlanet Maemo

Q2 2015 Community Council Election Announcement

Dear friends and Maemoans, six months and even a bit more has passed and again it is time to elect a new Community Council for us.

The last election finished on Saturday 3rd of January 2015 so we are running little late with the next one.

The schedule of the voting is as follows:

To get our community to continue strong, we need fresh people with fresh viewpoints to carry on the torch, so please think about volunteering for Maemo Council.

At the same time during the Council election we will also be running a referendum on Council rules. The referendum will be announced shortly.

On behalf of the outgoing community council,

Jussi Ohenoja

0 Add to favourites0 Bury

18 Jul 2015 4:57pm GMT

New syscalls for armv8-64 kernel

I decided to use a different target platform for my project. Initially, I was using Android Kitkat + Galaxy Nexus (ARMv7 + TI OMAP 4460). To obtain best performance with some crypto operations, I am now using Android Lollipop + Nexus 9 (ARMv8 64bits). I did some tests with basic OpenSSL examples (for example, AES-128 and SHA1) and the numbers are impressive.

The goal of this post is to document some problems that I had building the Android image and its respective kernel. You might think that I am being redundant, as you [might] have the same issues with a traditional Linux kernel. I've done this only for Android platform, so I don't know for other kernels. I'm also having some other problems, such as ARMv8-64 asm file compilation inside the kernel, but this will be described in another poster.

Basically, in my project, I have to create new syscalls and also change the sys_call_table to intercept existing ones, such as NR_write, NR_open, etc. You can check another post that describes how to create new syscalls and how to intercept existing syscalls. So, what is different?

1. Some syscalls have changed, some have been created and some others are not supported anymore.


__NR_open, __NR_link, __NR_chmod, __NR_rename, ... are not supported anymore. Instead, you should use __NR_openat, __NR_mkdirat, ...

For example, check the syscalls under the #def body __ARCH_WANT_SYSCALL_DEPRECATED and __ARCH_WANT_SYSCALL_NO_AT (file include/uapi/asm-generic/unistd.h)

In addition, the syscall number has also been changed. For example, NR_write changed from 3 to 63. Remember to change your code in userpsace that has any reference to one of these numbers.

2. Much easier than before: now, you only need to change less files. Add the definition of your syscalls in the following files:


include/linux/syscalls.h

...
asmlinkage long sys_seccomp(unsigned int op, unsigned int flags,
const char __user *uargs);

asmlinkage long sys_my_syscall(void __user *buf);
...

include/uapi/asm-generic/unistd.h

...
#define __NR_seccomp 277
__SYSCALL(__NR_seccomp, sys_seccomp)

#define __NR_my_syscall 278
__SYSCALL(__NR_my_syscall, sys_my_syscall)

#undef __NR_syscalls
#define __NR_syscalls 279
...

kernel/my_syscall_code.c (this file should contain the implementation of your syscall)

kernel/Makefile

obj-y = ....
...
async.o range.o groups.o lglock.o smpboot.o \
my_syscall_code.o
...

3. Don't forget to add asm/unistd.h as part of your head files.


4. Kernel modules are implemented the same way as before. To build it, remember to set cflags properly


There's just a small change on building the module. Call make with CFLAGS_MODULE=-fno-pic

5. And of course, the syscall table address table has changed as well.


Check the symbol sys_call_table in the file System.map.

As said, I am having other problems with it. In my case, I want to add some assembly files into my module and compile them all together. The point is that they are written in a specific format that GCC does not understand, but clang. So, things would be solved if I could use clang to build my module, but it doesn't work like that :-( Let's what comes next!

EDIT (31/07/2015) : this is a good guide for 32 bits -> 64 bits porting

0 Add to favourites0 Bury

18 Jul 2015 4:17pm GMT

30 Jun 2015

feedPlanet Maemo

2015-06-16 Meeting Minutes

Meeting held 2015-06-16 on FreeNode, channel #maemo-meeting (logs)

Attending: Jussi Ohenoja (juiceme), Peter Leinchen (peterleinchen)

Partial: Gido Griese (Win7Mac)

Absent: Oksana Tkachenko (Oksana/Wikiwide), William McBee (gerbick), Alexander Kozhevnikov (MentalistTraceur)

Summary of topics (ordered by discussion):


p>(Topic Referendum and Elections announcement):


Action Items:
  • old items:
    • The selected Code of Conduct (KDE) still needs to be published on TMO.
    • Looking into automatic calculation of election results ...
    • Contacting freemangordon and merlin1991 about auto-builder: CSSU-thumb target, GCC versions?
    • Getting maemo trademark registration (everywhere?) renewed (and transferred to MCeV) by the end of February (or within six months since expiry date).
    • Archiving Ovi/Nokia store, especially for Harmattan.
    • Contacting Daphne Won on Facebook and LinkedIn to get administrator rights on Facebook for a Maemo member to migrate the plugin to v2.0 API and maintain it in the future.
  • new items:

0 Add to favourites0 Bury

30 Jun 2015 4:11pm GMT

14 Jun 2015

feedPlanet Maemo

UEvents in Android - from kernel events to notifications

In my current project, the system has to notify the user about a certain action that actually takes place inside the kernel (in this case, transfer of security keys). I don't want to get into too much details about the tasks, but let's consider that the kernel and the Dalvik are the only trustworthy components and the security keys are stored inside the kernel. I've also seen some pieces of code that helps to implement this, but I could not find a end-to-end solution.

[This post is a bit long, as it contains a lot of code and I tried to explain some details of it.]

Ok, let's proceed. This is the flow:

1) The kernel is asked to perform a certain syscall (transfer securely stored keys inside the kernel);
2) The kernel has to notify the user that some application has asked to do something suspicious, for example, to have access to some security keys;
3) The event is sent all the way to the userspace and a notification appears to the user (UI).

First, we have to generate one event in the kernel space (you can create a module and insert your code there). For this, we use an UEVENT. In addition, we can also add extra pieces of information into the event, for example strings, integers and so forth. The following code shows a simple UEVENT generated from the kernel space. It contains one integer field called "etype".

Some pieces of code were taken from the kernel itself (linux/samples/kobject/kset-example.c), and I made small changes to keep it even simpler. For more information, check the original one.

Initially, we need to create a kobject to embedded an attribute, for instance (https://www.kernel.org/doc/Documentation/kobject.txt). Once the kobject is registered, we broadcast it to other components of the system using kobject_uevent(). The files foo_kobject.c/h and foo_event.c/h contain code to broadcast an UEvent using a kobject.

foo_kobject.h (kernel code, for example, as part of your module)

#ifndef FOO_KOBJECT_
#define FOO_KOBJECT_

/*
* Partially copied from linux/samples/kobject/kset-example.c
*
* Released under the GPL version 2 only.
*/

/*
* This is our "object" that we will create and register it with sysfs.
*/
struct foo_obj {
struct kobject kobj;
int foo;
};
#define to_foo_obj(x) container_of(x, struct foo_obj, kobj)

struct foo_obj *
create_foo_obj(const char *name);

int
foo_kobj_init(void);

void
foo_kobj_exit(void);

#endif


foo_kobject.c (kernel code, for example, as part of your module)

/*
* Partially copied from linux/samples/kobject/kset-example.c
*
* Released under the GPL version 2 only.
*
*/

#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>

#include "foo_kobject.h"

/*
* This module shows how to create a kset in sysfs called
* /sys/kernel/foo
* Then one kobject is created and assigned to this kset, "foo".
* In this kobject, one attribute is also
* created and if an integer is written to these files, it can be later
* read out of it.
*/

/* a custom attribute that works just for a struct foo_obj. */
struct foo_attribute {
struct attribute attr;
ssize_t (*show)(struct foo_obj *foo, struct foo_attribute *attr, char *buf);
ssize_t (*store)(struct foo_obj *foo, struct foo_attribute *attr, const char *buf, size_t count);
};
#define to_foo_attr(x) container_of(x, struct foo_attribute, attr)

/*
* The default show function that must be passed to sysfs. This will be
* called by sysfs for whenever a show function is called by the user on a
* sysfs file associated with the kobjects we have registered. We need to
* transpose back from a "default" kobject to our custom struct foo_obj and
* then call the show function for that specific object.
*/
static ssize_t foo_attr_show(struct kobject *kobj,
struct attribute *attr,
char *buf)
{
struct foo_attribute *attribute;
struct foo_obj *foo;

attribute = to_foo_attr(attr);
foo = to_foo_obj(kobj);

if (!attribute->show)
return -EIO;

return attribute->show(foo, attribute, buf);
}

/*
* Just like the default show function above, but this one is for when the
* sysfs "store" is requested (when a value is written to a file.)
*/
static ssize_t foo_attr_store(struct kobject *kobj,
struct attribute *attr,
const char *buf, size_t len)
{
struct foo_attribute *attribute;
struct foo_obj *foo;

attribute = to_foo_attr(attr);
foo = to_foo_obj(kobj);

if (!attribute->store)
return -EIO;

return attribute->store(foo, attribute, buf, len);
}

/* Our custom sysfs_ops that we will associate with our ktype later on */
static const struct sysfs_ops foo_sysfs_ops = {
.show = foo_attr_show,
.store = foo_attr_store,
};

/*
* The release function for our object. This is REQUIRED by the kernel to
* have. We free the memory held in our object here.
*
* NEVER try to get away with just a "blank" release function to try to be
* smarter than the kernel. Turns out, no one ever is...
*/
static void foo_release(struct kobject *kobj)
{
struct foo_obj *foo;

foo = to_foo_obj(kobj);
kfree(foo);
}

/*
* The "foo" file where the .foo variable is read from and written to.
*/
static ssize_t foo_show(struct foo_obj *foo_obj, struct foo_attribute *attr,
char *buf)
{
return sprintf(buf, "%d\n", foo_obj->foo);
}

static ssize_t foo_store(struct foo_obj *foo_obj, struct foo_attribute *attr,
const char *buf, size_t count)
{
sscanf(buf, "%du", &foo_obj->foo);
return count;
}

static struct foo_attribute foo_attribute =
__ATTR(foo, 0666, foo_show, foo_store);

/*
* Create a group of attributes so that we can create and destroy them all
* at once.
*/
static struct attribute *foo_default_attrs[] = {
&foo_attribute.attr,
NULL, /* need to NULL terminate the list of attributes */
};

/*
* Our own ktype for our kobjects. Here we specify our sysfs ops, the
* release function, and the set of default attributes we want created
* whenever a kobject of this type is registered with the kernel.
*/
static struct kobj_type foo_ktype = {
.sysfs_ops = &foo_sysfs_ops,
.release = foo_release,
.default_attrs = foo_default_attrs,
};

static struct kset *example_kset;

struct foo_obj *create_foo_obj(const char *name)
{
struct foo_obj *foo;
int retval;

/* allocate the memory for the whole object */
foo = kzalloc(sizeof(*foo), GFP_KERNEL);
if (!foo)
return NULL;

/*
* As we have a kset for this kobject, we need to set it before calling
* the kobject core.
*/
foo->kobj.kset = example_kset;

/*
* Initialize and add the kobject to the kernel. All the default files
* will be created here. As we have already specified a kset for this
* kobject, we don't have to set a parent for the kobject, the kobject
* will be placed beneath that kset automatically.
*/
retval = kobject_init_and_add(&foo->kobj, &foo_ktype, NULL, "%s", name);
if (retval) {
kobject_put(&foo->kobj);
return NULL;
}

/*
* We are always responsible for sending the uevent that the kobject
* was added to the system.
*/
kobject_uevent(&foo->kobj, KOBJ_ADD);

return foo;
}

static void destroy_foo_obj(struct foo_obj *foo)
{
kobject_put(&foo->kobj);
}

int
foo_kobject_init(void)
{
/*
* Create a kset with the name of "kset_foo",
* located under /sys/kernel/
*/
example_kset = kset_create_and_add("kset_foo", NULL, kernel_kobj);
if (!example_kset)
return -ENOMEM;

}

void
foo_kobject_exit(void)
{
destroy_foo_obj(foo_kobj);
kset_unregister(example_kset);
}


foo_uevent.h (kernel code, for example, as part of your module)

#ifndef FOO_UEVENT_
#define FOO_UEVENT_

enum FOO_event_type {
FOO_GET = 1,
FOO_SET
};

struct foo_event {
enum foo_event_type etype;
};

int foo_init_events(void);

int foo_send_uevent(struct foo_event *fooe);

#endif


In the following code, we send an event string as part of our new UEvent. In our case, just the type of the event (FOO_GET or FOO_SET). foo_uevent.c (kernel code, for example, as part of your module)

#include <linux/kobject.h>
#include "foo_kobject.h"
#include "foo_uevent.h"

static struct foo_obj *foo_kobj;

int foo_init_events(void)
{
int ret;

ret = example_init();
if (ret)
{
printk("error - could not create ksets\n");
goto foo_error;
}

foo_kobj = create_foo_obj("foo");
if (!foo_kobj)
{
printk("error - could not create kobj\n");
goto foo_error;
}

return 0;

foo_error:
return -EINVAL;
}

int foo_send_uevent(struct foo_event *pce)
{
char event_string[20];
char *envp[] = { event_string, NULL };

if (!foo_kobj)
return -EINVAL;

snprintf(event_string, 20, "FOO_EVENT=%d", pce->etype);

return kobject_uevent_env(&foo_kobj->kobj, KOBJ_CHANGE, envp);
}

So far, we've only made changes in the kernel level. But also, we need to listen to UEVENTs in the userspace. For that, I changed a little bit the Dalvik and added the following binder to listen to UEvents and send notifications, so that the user can see the event.

For more details on how to add a system service in Android, check this link. In this case, I added a Binder, as we are not providing any service (setting an integer, for instance). In our example, we simply broadcast events to the user interface.

To add the following Binder, create a file that contains the code into framework/base/services/java/com/android/server/. You also have to change the file Android.mk at framework/base/services/jni/Android.mk


...
LOCAL_SRC_FILES:= \
com_android_server_VibratorService.cpp \
com_android_server_location_GpsLocationProvider.cpp \
com_android_server_connectivity_Vpn.cpp \
+ com_android_server_pm_PackageManagerService.cpp \
onload.cpp
...


Also, don't forget to register the service (check the link that I mentioned before!), by changing the file framework/base/services/java/com/android/server/SystemServer.java


class ServerThread extends Thread {
...
WifiP2pService wifiP2p = null;
WifiService wifi = null;
NsdService serviceDiscovery= null;
+ MyServiceBinder myService = null;
IPackageManager pm = null;
Context context = null;
WindowManagerService wm = null;
...
class ServerThread extends Thread {
...
}

try {
+ Slog.i(TAG, "My Service - Example");
+ myService = MyServiceBinder.create(context);
+ ServiceManager.addService(
+ Context.MY_SERVICE, myService);
+ } catch (Throwable e) {
+ reportWtf("starting Privacy Capsules Service", e);
+ }
+
...


Finally, here is the Java code. This Binder simply listens to UEvents that contains the string "FOO_EVENT", which also embeds the integer as part of the UEvent. Then, we create a UI notification and we attach an Intent to the notification, so that when the user clicks on it, a Activity or a Dialog is launched.

...
public class MyServiceBinder extends Binder {

private final int FOO_GET = 1;
private final int FOO_SET = 2;

private MyServiceWorkerThread mWorker;
private MyServiceWorkerHandler mHandler;
private Context mContext;
private NotificationManager mNotificationManager;

/*
* We create an observer to listen to the UEvent we are interested in.
* See UEventObserver#startObserving(String). From the UEvent, we extract
* an existing integer field and we propagate create a notification to
* be seen by the user.
*/
private final UEventObserver mUEventObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
final int eventType = Integer.parseInt(event.get("FOO_EVENT"));
sendMyServiceNotification(eventType);
}
};

public MyServiceBinder(Context context) {
super();
mContext = context;
mNotificationManager = (NotificationManager)mContext.getSystemService(
Context.NOTIFICATION_SERVICE);

/* We have to specify a filter to receive only certain UEvents from the
* kernel. In this case, the UEVENT that we want to listen to contains
* the string "FOO_EVENT".
*/
mUEventObserver.startObserving("FOO_EVENT=");

mWorker = new MyServiceWorkerThread("MyServiceWorker");
mWorker.start();
}

/*
* Add potential initialization steps here
*/
public static MyServiceBinder create(Context context) {
MyServiceBinder service = new MyServiceBinder(context);
return service;
}

/*
* Sends notification to the user. In this case, we are create notifications.
* If the user clicks on the notification, we send an Intent so that an system
* application is launched. For example, if we are listening to notifications
* for USB UEvents, the USB Settings application can be launched when the
* notification is clicked.
*/
private final void sendNotificationToUser(int type) {
String notificationMessage = "";
Resources r = mContext.getResources();
switch(type) {
case FOO_GET:
// do something if the event type is A
notificationMessage = "This is event type FOO_GET";
break;
case FOO_SET:
// do something if the event type is B
notificationMessage = "This is event type FOO_SET";
break;
default:
break;
}

String notificationTitle = r.getString(R.string.my_service_notification_title);
long notificationWhen = System.currentTimeMillis();
int requestID = (int) notificationWhen;

Intent intent = new Intent(Intent.ACTION_FOO_EVENT);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);

intent.putExtra(FooManager.EXTRA_ETYPE, type);
intent.putExtra(FooManager.EXTRA_MESSAGE, notificationMessage);

PendingIntent pi = PendingIntent.getActivityAsUser(mContext, requestID,
intent, 0, null, UserHandle.CURRENT);

Notification notification = new Notification.Builder(mContext)
.setSmallIcon(R.drawable.indicator_input_error)
.setContentTitle(notificationTitle)
.setContentText(notificationMessage)
.setPriority(Notification.PRIORITY_HIGH)
.setDefaults(0)
.setWhen(notificationWhen)
.setOngoing(true)
.setContentIntent(pi)
.setAutoCancel(true)
.build();

mNotificationManager.notifyAsUser(null,
R.string.my_service_notification_title,
notification, UserHandle.ALL);
}


/*
* Runner for the
*
*/
private void sendMyServiceNotification(final int type) {

mHandler.post(new Runnable() {
@Override
public void run() {
sendNotificationToUser(type);
}
});

}

private class MyServiceWorkerThread extends Thread {

public MyServiceWorkerThread(String name) {
super(name);
}

public void run() {
Looper.prepare();
mHandler = new MyServiceWorkerHandler();
Looper.loop();
}

}

private class MyServiceWorkerHandler extends Handler {

private static final int MESSAGE_SET = 0;

@Override
public void handleMessage(Message msg) {
try {
if (msg.what == MESSAGE_SET) {
Log.i(TAG, "set message received: " + msg.arg1);
}
} catch (Exception e) {
// Log, don't crash!
Log.e(TAG, "Exception in MyServiceWorkerHandler.handleMessage:", e);
}
}

}
}

0 Add to favourites0 Bury

14 Jun 2015 4:43pm GMT

12 Jun 2015

feedPlanet Maemo

2015-06-02 Meeting Minutes

Meeting held 2015-06-02 on FreeNode, channel #maemo-meeting (logs)

Attending:
William McBee (gerbick), Jussi Ohenoja (juiceme), Peter Leinchen (peterleinchen),

Gido Griese (Win7Mac),

Partial: Oksana Tkachenko (Oksana/Wikiwide),
Rüdiger Schiller (chem|st),

Absent: Alexander Kozhevnikov (MentalistTraceur),

Summary of topics (ordered by discussion):


Topic (Referendum):


Action Items:
  • -- old items:
    • The selected Code of Conduct (KDE) still needs to be published on (T)MO.
    • Looking into automatic calculation of election results ...
    • Contacting freemangordon and merlin1991 about auto-builder: CSSU-thumb target, GCC versions?
    • Getting maemo trademark registration (everywhere?) renewed (and transferred to MCeV) by the end of February (or within six months since expiry date).
    • archiving Ovi/Nokia store, especially for Harmattan.
    • Contacting Daphne Won on Facebook and LinkedIn to get administrator rights on Facebook for a Maemo member to migrate the plugin to v2.0 API and maintain it in the future.
  • -- new items:

0 Add to favourites0 Bury

12 Jun 2015 7:09am GMT

2015-05-19 Meeting Minutes

Meeting held 2015-05-19 on FreeNode, channel #maemo-meeting (logs)

Attending:
William McBee (gerbick), Jussi Ohenoja (juiceme),

Gido Griese (Win7Mac),

Partial: Oksana Tkachenko (Oksana/Wikiwide),

Absent: Peter Leinchen (peterleinchen), Alexander Kozhevnikov (MentalistTraceur),

Summary of topics (ordered by discussion):


Topic (HiFo and MCeV: transfer):

Topic (Referendum):


Action Items:
  • -- old items:
    • The selected Code of Conduct (KDE) still needs to be published on (T)MO.
    • Looking into automatic calculation of election results ...
    • Contacting freemangordon and merlin1991 about auto-builder: CSSU-thumb target, GCC versions?
    • Getting maemo trademark registration (everywhere?) renewed (and transferred to MCeV) by the end of February (or within six months since expiry date).
    • archiving Ovi/Nokia store, especially for Harmattan.
    • Contacting Daphne Won on Facebook and LinkedIn to get administrator rights on Facebook for a Maemo member to migrate the plugin to v2.0 API and maintain it in the future.
  • -- new items:

0 Add to favourites0 Bury

12 Jun 2015 6:58am GMT

19 May 2015

feedPlanet Maemo

2015-05-12 Meeting Minutes

Meeting held 2015-05-12 on FreeNode, channel #maemo-meeting (logs)

Attending:
Jussi Ohenoja (juiceme), Peter Leinchen (peterleinchen),

Ivaylo Dimitrov (freemangordon),

Partial: Oksana Tkachenko (Oksana/Wikiwide),
Falk Stern (warfare/fstern),

Absent: William McBee (gerbick), Alexander Kozhevnikov (MentalistTraceur),

Summary of topics (ordered by discussion):


Topic (HiFo and MCeV: transfer):

Topic (Referendum):

Topic (Facebook API changes):


Action Items:
  • -- old items:
    • The selected Code of Conduct (KDE) still needs to be published on (T)MO.
    • Looking into automatic calculation of election results ...
    • Contacting freemangordon and merlin1991 about auto-builder: CSSU-thumb target, GCC versions?
    • Getting maemo trademark registration (everywhere?) renewed (and transferred to MCeV) by the end of February (or within six months since expiry date).
    • archiving Ovi/Nokia store, especially for Harmattan.
    • Contacting Daphne Won on Facebook and LinkedIn to get administrator rights on Facebook for a Maemo member to migrate the plugin to v2.0 API and maintain it in the future.
  • -- new items:

0 Add to favourites0 Bury

19 May 2015 6:12am GMT

16 May 2015

feedPlanet Maemo

2015-05-05 Meeting Minutes

Meeting held 2015-05-05 on FreeNode, channel #maemo-meeting (logs)

Attending:
Jussi Ohenoja (juiceme), Peter Leinchen (peterleinchen),

Ivaylo Dimitrov (freemangordon),

Partial: Oksana Tkachenko (Oksana/Wikiwide),
Gido Griese (Win7Mac),

Absent: William McBee (gerbick), Alexander Kozhevnikov (MentalistTraceur),

Summary of topics (ordered by discussion):


Topic (Facebook API changes):

Topic (Referendum, repositories being down and the letter to HiFo):


Action Items:
  • -- old items:
    • The selected Code of Conduct (KDE) still needs to be published on (T)MO.
    • Looking into automatic calculation of election results ...
    • Contacting freemangordon and merlin1991 about auto-builder: CSSU-thumb target, GCC versions?
    • Getting maemo trademark registration (everywhere?) renewed (and transferred to MCeV) by the end of February (or within six months since expiry date).
    • archiving Ovi/Nokia store, especially for Harmattan.
  • -- new items:
    • Contacting Daphne Won to get administrator rights for a Maemo member to migrate the plugin to v2.0 API and maintain it in the future.

0 Add to favourites0 Bury

16 May 2015 12:57am GMT