dkim_dstring_cat() can be made more efficient by replacing the use of 'sm_strlcat' with memcpy() as you already know:
1) The size of the old string, so you can memcpy directly onto the end
2) You know the size of the string being added (from a previous strlen() to figure out if you needed to grow the buffer)
3) And you also know that the buffer is large enough, because it was already expanded if needed
On very large strings where you are dkim_dstring_cat()ing something onto the end, this can be a decent performance improvement.
There are other cases throughout the libdkim code that can be made more efficient similarly:
995 if (sm_strlcat(restr, "$", sizeof restr) >= sizeof restr)
996 return FALSE;
It looks like that can be converted into "*q = '$'" if 'q' is not pointing past the end of 'restr'.
1921 snprintf(tmp, sizeof tmp, ";%sbh=%s", delim,
1923 sm_strlcat(tmphdr, tmp, sizeof tmphdr);
The return from 'snprintf' can be cached there and used to replace strlcat with a strlcpy.